Windosで、CD(DVD)トレイを開閉する
結構悩んでしまった、
CD/DVDトレイ開閉スクリプト - IT生活向上ブログ
wmp = WIN32OLE.new 'WMPlayer.OCX' f = wmp.cdromcollection.getByDriveSpecifier('F:') f.eject f.eject
「F:」は光学ドライブのドライブレター、手元ではそうでした。
同じドライブオブジェクトに対し ejectメソッドを繰り返すとトレイが閉じます、オブジェクトを作り直してしまうと閉じなくなるの注意。そのときは二度 eject呼ぶと閉じます。
一行スクリプトで閉じるならこんな感じか
WIN32OLE.new('WMPlayer.OCX').cdromCollection.item(0).tap{|f|f.eject}.eject
そして WIN32OLE.new('WMPlayer.OCX')オブジェクトや、WIN32OLE.new('WMPlayer.OCX').cdromCollectionオブジェクトが捕まえてる間はドライブの電源を切れなかったり。
http://www.microsoft.com/japan/technet/scriptcenter/resources/qanda/apr06/hey0417.mspx
そしてトレイを開いたり閉じたりする(一行)スクリプト、もうドライブ指定しなくていいじゃん、それっぽいの最初で。
PuTTYで生成した公開鍵を使う
どこで見たんだっけな、PuTTYgen で生成したキーペアについて。公開鍵を Linux機に仕込む。
ssh-keygen -i -f id_rsa.pub >> authorized_keys
ちなみに -iオプションは
-i This option will read an unencrypted private (or public) key file in SSH2-compatible format and print an OpenSSH compatible private (or public) key to stdout. ssh-keygen also reads the RFC 4716 SSH Public Key File Format. This option allows importing keys from several commercial SSH implementations.
経過分秒表示(続)
前に同じような事もあった(time.rb 経過分秒表示 - Rubyとか Illustratorとか SFとか折紙とか)のだが、やはりライトニングトーク絡みで時間表示を作ってみた(申し込んだLT自体は reject)。取敢えずソース
LT_timer.rb (このソースはその後更新されています、11/1/2)
#coding:Windows-31J # $Id: LT_timer.rb 3582 2010-07-04 09:32:14Z hs9587 $ # $Date: 2010-07-04 18:32:14 +0900 (譌・, 04 7 2010) $ # $Name$ $Author: hs9587 $ $Revision: 3582 $ Version = "0.0 ($Revision: 3582 $)" require 'vr/vruby' require 'vr/vrcontrol' require 'vr/vrtimer' require 'vr/vrlayout' require 'time' Min = Time.parse('00:01')-Time.parse('00:00') class TimerControl < VRPanel include VRTimerFeasible include VRDrawable SrartResetStruct= Struct.new :name, :button, :body StartReset = [ SrartResetStruct.new('start', '!' \ , lambda{@start_time = Time.now; def anchor_time; @start_time; end}), SrartResetStruct.new('reset', '0' \ , lambda{def anchor_time; Time.now; end}), SrartResetStruct.new('exit', '.', lambda{exit}), ] attr_writer :time_out, :time_color def construct self.caption = 'LTTimer' #addTimer 1000 addTimer 50 @font = @screen.factory.newfont 'MS ゴシック', -72 #@font = @screen.factory.newfont 'HG ゴシックE', -72 #@font = @screen.factory.newfont 'HGS ゴシックE', -72 #@font = @screen.factory.newfont 'Tahoma', -72, 400, 0, 0, 0, 34, 0 #@font = @screen.factory.newfont 'Tahoma', -72 @time_out = 5.0 @time_color = 3.0 end # def construct def self_paint elapse = Time.at((Time.now - anchor_time).abs) self.textColor = RGB elapsed(elapse), 0, 0 mm_ss = elapse.strftime '%M:%S' setFont @font #p textExtent(mm_ss) drawText mm_ss, 0,0, *textExtent(mm_ss) end # def self_paint def self_timer refresh end StartReset.each do |start_reset| define_method start_reset.name, start_reset.body end # StartReset.each do |start_reset| private def anchor_time Time.now end # def anchor_time def elapsed(sec) sec = sec.to_i case sec when 0 ... Min*@time_color then 0 when Min*@time_color ... Min*@time_out then 256 * (sec - Min*@time_color) / (Min*(@time_out - @time_color)) else sec < 0 ? 0 : 255 end # case sec end # def elapsed(sec) end # class TimerControl < VRPanel class StartResetControl < VRPanel include VRVertLayoutManager include VRStdControlContainer def construct TimerControl::StartReset.each do |start_reset| addControl VRButton, start_reset.name, start_reset.button send_parent start_reset.name, 'clicked' end # TimerControl::StartReset.each do |start_reset| end # def construct end # class StartResetControl < VRPanel module LTTimer attr_reader :timer def construct self.caption = 'LTTimer' move 0,0, 198,104 addControl TimerControl, 'timer', 'Timer', 0,0, 180,72 addControl StartResetControl, 'buttons', 'Buttons', 181,0, 10,72 top 0xffffffff end # def construct TimerControl::StartReset.each do |start_reset| define_method("buttons_#{start_reset.name}_clicked") do @timer.send start_reset.name end # define_method("buttons_#{start_reset.name}_clicked") do end # TimerControl::StartReset.each do |start_reset| end # module LTTimer time_out, time_color, start = 5, 3, false require 'optparse' ARGV.options do |opt| opt.on('-o', '--timeout=VAL', 'default: 5(min)'){|v| time_out = v.to_f} opt.on('-c', '--timecolor=VAL', 'default: 3(min)'){|v| time_color = v.to_f} opt.on('-s', '--[no-]start', 'default: no'){|v| start = v} opt.banner << "\nLeft upper topmost timer" begin # rescue OptionParser::ParseError => evar opt.parse! rescue OptionParser::ParseError => evar evar.display $stderr; "\n".display $stderr opt.help.display $stderr exit 1 end # rescue OptionParser::ParseError => evar end # ARGV.options do |opt| begin # rescue SystemStackError => evar #VRLocalScreen.start LTTimer lt = VRLocalScreen.showForm LTTimer lt.timer.time_out = time_out lt.timer.time_color = time_color lt.timer.start if start VRLocalScreen.messageloop rescue SystemStackError => evar end # rescue SystemStackError => evar
WindowsでVisualuRuby を使って時間(分秒)表示する GUI時計を作ります。一応 5分計で、途中 3分から表示色を赤っぽくし始め 5分で赤くします。コマンドラインオプションからその辺のタイミングを設定するのはOptionParser (optparse) です。
その表示色なんですが 3分から RGBの値を変えていくのに、実際のところ 3分では全然分かりません。3分半でもしかしてら色変えてますかという程度。4分でそれは褐色かもと見えるようになり、4分半でかなり赤く、そして4分45秒くらいでもう真っ赤、そのまま 5分以降も赤いです。
以下、順次メモ書き。
Version とか require
#coding:Windows-31J # $Id: LT_timer.rb 3582 2010-07-04 09:32:14Z hs9587 $ # $Date: 2010-07-04 18:32:14 +0900 (譌・, 04 7 2010) $ # $Name$ $Author: hs9587 $ $Revision: 3582 $ Version = "0.0 ($Revision: 3582 $)" require 'vr/vruby' require 'vr/vrcontrol' require 'vr/vrtimer' require 'vr/vrlayout' require 'time' Min = Time.parse('00:01')-Time.parse('00:00')
Version定数は後で OptionParser (optparse) の --version 表示に拾って貰う用、subversion の更新文字列を混ぜてる。
そして VisuzluRuby関係の require、vruby は全体的なもの、vrcontrol は釦とか使うので、vrtimer はタイマーの自動画面更新用、vrlayout は釦を配置するときのレイアウトマネージャー。
time はそして Min = 60 の計算用、一分が60秒ってのは即値で書いちゃってもいいのかな。定数 Min の名前はちょっと迷う、最小とか誤解しないか、でもあんまり長いのもなんだし。
タイマー表示のVRコントロール
class TimerControl < VRPanel
タイマー表示の導入
class TimerControl < VRPanel include VRTimerFeasible include VRDrawable SrartResetStruct= Struct.new :name, :button, :body StartReset = [ SrartResetStruct.new('start', '!' \ , lambda{@start_time = Time.now; def anchor_time; @start_time; end}), SrartResetStruct.new('reset', '0' \ , lambda{def anchor_time; Time.now; end}), SrartResetStruct.new('exit', '.', lambda{exit}), ] attr_writer :time_out, :time_color
include はまあそんな感じ。Struct構造体を定義しての StartReset配列にはこの後のコントロール釦の名前や表示、動作を登録する。このコントロールを含む三つのクラス(モジュール)定義で共用するものなので一箇所に登録する。lambdaブロックの動作の為か、このクラス内で定義しないとうまく動かなかったのでここに。
釦の動作は、exitはまあ良いとして、あとの二つは後ろの方で定義するプライベートメソッド anchor_time の再定義。釦押下時点を記録してその時間を返すか、現在時刻を返すか。
そして :time_out, :time_color はコマンドラインオプションからやってきたりする文字色変更のタイミング、というかタイマー期限。
コンストラクタとフォントの事
def construct self.caption = 'LTTimer' #addTimer 1000 addTimer 50 @font = @screen.factory.newfont 'MS ゴシック', -72 #@font = @screen.factory.newfont 'HG ゴシックE', -72 #@font = @screen.factory.newfont 'HGS ゴシックE', -72 #@font = @screen.factory.newfont 'Tahoma', -72, 400, 0, 0, 0, 34, 0 #@font = @screen.factory.newfont 'Tahoma', -72 @time_out = 5.0 @time_color = 3.0 end # def construct
コンストラクタの意義としては addTimer かな。あんまり長いと秒表示のずれがひどいし短いとちらつく。もう少しだけ長くてもいいかも。コメントアウトしてる 1000 は参考にした「フォントを選べる時計」での値。
とはいえそれを参考にしてもフォントの指定方法は良く分からなかったので 'MS ゴシック' 72サイズ。本当は Tahoma とか使いたかったんだけどどうも位置がずれる、大体「-72」の「-(マイナス)」って何だ。
分秒の表示
def self_paint elapse = Time.at((Time.now - anchor_time).abs) self.textColor = RGB elapsed(elapse), 0, 0 mm_ss = elapse.strftime '%M:%S' setFont @font #p textExtent(mm_ss) drawText mm_ss, 0,0, *textExtent(mm_ss) end # def self_paint def self_timer refresh end
実際の表示と再表示、メソッド名は VisualuRuby に従うもの。
表示時間は achor_timeプライベートメソッドと現在時刻の差、achor_timeメソッドの動作によってタイマーが進むのか止まってるのか決まる。そしてそれを elapsedプライベートメソッドに渡して文字色を調整する。
コントロール系のメソッド
StartReset.each do |start_reset| define_method start_reset.name, start_reset.body end # StartReset.each do |start_reset|
釦押下時の動作(メソッド)を定義、前掲配列を当たって三つ。
プライベートメソッド
private def anchor_time Time.now end # def anchor_time def elapsed(sec) sec = sec.to_i case sec when 0 ... Min*@time_color then 0 when Min*@time_color ... Min*@time_out then 256 * (sec - Min*@time_color) / (Min*(@time_out - @time_color)) else sec < 0 ? 0 : 255 end # case sec end # def elapsed(sec) end # class TimerControl < VRPanel
タイマー開始時を返す anchor_time と、タイマー経過時間に対して文字色を返す elapsed。色の計算には起動時にセットされるインスタンス変数 @time_out, @time_color を用いる
操作用釦のVRコントロール
class StartResetControl < VRPanel include VRVertLayoutManager include VRStdControlContainer def construct TimerControl::StartReset.each do |start_reset| addControl VRButton, start_reset.name, start_reset.button send_parent start_reset.name, 'clicked' end # TimerControl::StartReset.each do |start_reset| end # def construct end # class StartResetControl < VRPanel
レイアウトマネージャを使って釦を配置、釦定義には前掲配列を当たる。
タイマー本体
module LTTimer attr_reader :timer def construct self.caption = 'LTTimer' move 0,0, 198,104 addControl TimerControl, 'timer', 'Timer', 0,0, 180,72 addControl StartResetControl, 'buttons', 'Buttons', 181,0, 10,72 top 0xffffffff end # def construct TimerControl::StartReset.each do |start_reset| define_method("buttons_#{start_reset.name}_clicked") do @timer.send start_reset.name end # define_method("buttons_#{start_reset.name}_clicked") do end # TimerControl::StartReset.each do |start_reset| end # module LTTimer
本体の定義、既に定義したタイマー表示部分と釦配置の二つのコントロールを配置する。サイズは即値でここに書く、表示してみないと表示領域の大きさが分からないのでいろいろやってみた。大きさ動的にとるの難しい。あと、top の指定でタイマーを最前面表示する。
それとやはり前掲配列を当たって、釦のコントローラから釦押下を受け取ってタイマー表示のコントローラに受け渡すメソッドを定義。タイマー表示のコントローラは @timerインスタンス変数にいれてる。
コマンドラインとオプション変数
time_out, time_color, start = 5, 3, false require 'optparse' ARGV.options do |opt| opt.on('-o', '--timeout=VAL', 'default: 5(min)'){|v| time_out = v.to_f} opt.on('-c', '--timecolor=VAL', 'default: 3(min)'){|v| time_color = v.to_f} opt.on('-s', '--[no-]start', 'default: no'){|v| start = v} opt.banner << "\nLeft upper topmost timer" begin # rescue OptionParser::ParseError => evar opt.parse! rescue OptionParser::ParseError => evar evar.display $stderr; "\n".display $stderr opt.help.display $stderr exit 1 end # rescue OptionParser::ParseError => evar end # ARGV.options do |opt|
optparse を使ってコマンドラインオプションを受け取る。文字色を変えるタイミングと起動時にタイマーをスタートさせてるか止めてるかの選択。opt.banner にて Usage文字列に説明を付加。
実行
begin # rescue SystemStackError => evar #VRLocalScreen.start LTTimer lt = VRLocalScreen.showForm LTTimer lt.timer.time_out = time_out lt.timer.time_color = time_color lt.timer.start if start VRLocalScreen.messageloop rescue SystemStackError => evar end # rescue SystemStackError => evar
セットされたコマンドオプションを設定して .messageloopを起動。オプションを設定する必要があるのでコメントアウトしてるような .startで一気に実行というのはない。
exit を呼ぶとちょっと階層深くなってるのか SystemStackError が発生するので begin rescue で囲ってある。
VisualuRuby
GUI表示には、Windows という事で VisualuRuby(VisualuRuby計画(仮称))を用いた。なかなか説明とか資料が見付からなくて苦労する。上記プロジェクトのページと、そこにも記載のあるサンプル(VisualuRuby計画(仮称) サンプル)を参考に考える。
SystemStackErrorのこと(/7/25 追記)
メイン(実行)パートの SystemStackError だけど単純な僕の間違いだった。
StartReset定数の3項目
SrartResetStruct.new('exit', '.', lambda{exit}),
これは TimerControlコントローラの中ではメソッド定義に用いる。その実行ブロックでは「Kernel.#exit」メソッドを呼んでプログラム全体を終了しようとするつもりのに、メソッド名自体を「exit」にしてるので自身を呼ぶ事になって循環してしまう。そしてこのエラーになる。
ということで StartReset定数は書き換え、メソッド名は「close」にでもしましょう。
StartReset = [ SrartResetStruct.new('start', '!' \ , lambda{@start_time = Time.now; def anchor_time; @start_time; end}), SrartResetStruct.new('reset', '0' \ , lambda{def anchor_time; Time.now; end}), SrartResetStruct.new('close', '.', lambda{exit}), ]
そしてメイン(実行)ブロックは begin, rescue節で囲う事もなく。
#VRLocalScreen.start LTTimer lt = VRLocalScreen.showForm LTTimer lt.timer.time_out = time_out lt.timer.time_color = time_color lt.timer.start if start VRLocalScreen.messageloop
Windows7 での細々した設定
Windows 7 Professional (64bit版) を使い始めた。で、初期設定とか細々した辺り、先週志村 (@hs9587) | Twitterしたものから転載(誤字ちょっと修正)。
ログオン時の背景画像の変更、C:\windows\System32\oobe\info\BACKGROUNDS\BACKGROUNDDEFAULT.JPG を同名の別 jpeg画像ファイルに差し替える。大きさ制限 250Kまで、とか、かも。 Windows7 2:29 PM Nov 27th webで
ファイル拡張子の表示。コントロールパネル-デスクトップのカスタマイズ-フォルダーオプション-表示-詳細設定-登録されている拡張子は表示しない、のチェックを外す。 Windows7 8:16 PM Nov 26th webで
他にも隠しファイルの表示非表示とかその辺りはこの辺に。
ログイン時のユーザ名表示の抑制。コントロールパネル-システムとセキュリティ-管理ツール-ローカルセキュリティポリシー-ローカルポリシー-セキュリティオプション-対話型ログオン: 最後のユーザー名を表示しない-プロパティ、で有効に設定。140字以内で書けた! Windows7 5:35 PM Nov 26th webで
パスワードの長さ難さとかその辺りもこの辺。
取り敢えずマウス調整、早くする。ポインター画像、待ちは最初からアニメーションだった、ドーナツぐるぐる、Windows7 3:30 PM Nov 26th webで
Windows7(64bit)始めました。でもなんだかよく分かりません、混乱しています。 2:59 PM Nov 26th webで
PGconn#quote_ident の有無
昨日 PGconn#quote_ident - Rubyとか Illustratorとか SFとか折紙とか の続き。
大事な事、Debian lenny で libpgsql-ruby を使ってた方は大丈夫だったです、他でも新しめの環境なら大丈夫なのでしょう。
- Rails(ActiveRecord) 2.3.3 <- 2.3.2 のヴァージョンアップで、activerecord-2.3.#/lib/active_record/connection_adapters/postgresql_adapter.rb の中の quote_column_name(name)メソッドの実装が変わった
- 単に「%("#{name}")」としていたものから「PGconn.quote_ident(name.to_s)」へ
- Debian の libpgsql-ruby1.8 の提供する Rubyライブラリは lenny では pg.so だが、etch では postgres.so たった
- postgres.so の提供する PGconnクラスに所要の quote_ident は定義されていない
- それはそれとして上記 postgresql_adapter.rb 冒頭ではまずライブラリでかジェムでか知らず 'pg' を requireしようとし、駄目だったら 'postgres' を requireする(そしてメソッド名とかちょこっと調整する)
という訳で、未だに Debian etch を引きずってるのが駄目だった模様。
etchの場合
そういうわけで、ActiveRecord(postgresql_adapter.rb) のライブラリ切換えを利用することにして、site_ruby にちょっと pg.rb とか置いて誤摩化す。これで Railsアプリケーションレベルでの昨日みたいなちょっとなんとかはせずに済むようになる。
/usr/local/lib/site_ruby/pg.rb
require 'postgres' class PGconn unless self.respond_to? :quote_ident then def self.quote_ident(name) '"' + name + '"' end # def self.quote_ident(name) end # unless self.respond_to? :quote_ident end # class PGconn class PGresult alias_method :nfields, :num_fields unless self.method_defined?(:nfields) alias_method :ntuples, :num_tuples unless self.method_defined?(:ntuples) alias_method :ftype, :type unless self.method_defined?(:ftype) alias_method :cmd_tuples, :cmdtuples unless self.method_defined?(:cmd_tuples) end # class PGresult
site_ruby か site_ruby/1.8 か、或いは vender_ruby以下とかは大変迷う。 PGresult方面は上記 postgresql_adapter.rb 冒頭での調整事項、ここが繰り返しになるのはちょっとやなんだけどね
Windowsの場合
こっちの方ではポスグレのドライバーとしては gem の postgres-pr を使っている (PostgreSQLサーバ自体は近在の Linux機)。そして gem の postgres はコンパイル不能でやっぱりインストール出来ない。「Could not find PostgreSQL build environment (libraries & headers): Makefile not created」
上記 etch での措置と同じやり方でも誤魔化せそうなんだけど折角 postgres-pr というちょっとだけ違う名前が使えるのでなんかやってみる。
C:\Program Files\ruby-1.8\lib\ruby\site_ruby\postgres.rb
require 'rubygems' require 'postgres-pr/postgres-compat' class PGconn unless self.respond_to? :quote_ident then def self.quote_ident(name) '"' + name + '"' end # def self.quote_ident(name) end # unless self.respond_to? :quote_ident end # class PGconn
postgres-prジェムの入れる postgres.rb は乗っ取ってしまうがその中でやってるのは postgres-pr/postgres-compat の呼び出しなのでそれを代行。rubygems を require しておくべきかどうかは微妙だが、いつもいつも Rails方面からの require だけでもあるまいと考えて。
pg として振舞うわけではだいので etch の時のようなメソッド名調整は無くて良い、そこはちょっとすっきりした。
関係ないけど rake cucumber:all
関係ないけどそんなことしてる間に「rake features」は時代遅れになっていた。「rake cucumber:all」だって、あと「ok」「wip」(work in progress 絶賛開発中)モードとか。