Plagger実行中にconfigを対話的に入力するプラグイン
パスワードが必要なプラグインを使う場合、config.yamlにパスワードを直接書いたりするようなのですが、対話的に入力させたいなあと思って実行中にパラメータを入力できるプラグインを作ってみました。(既にあったら悲しい)
使い方
例えばCustomFeed::Mixiの場合、
plugins: - module: CustomFeed::Mixi config: email: email@example.com password: password fetch_body: 1 show_icon: 1 feed_type: - RecentComment - FriendDiary - Message - module: Publish::Debug
のように書きますが、以下のようにすることでconfig.yamlを書き換えずに実行時にemailとpasswordを入力させることができます。
plugins: - module: CustomConfig config: - ReadLine: prompt: "What is your Mixi's email? [email@example.com] " name: email - ReadPassword: prompt: "What is your Mixi's password? [password] " name: password - module: CustomFeed::Mixi config: email: email@example.com password: password fetch_body: 1 show_icon: 1 feed_type: - RecentComment - FriendDiary - Message - module: Publish::Debug
CustomConfig内のconfigで指定されたプラグインが上から順に処理されます。ReadLineでは一時停止し一行入力待ちとなります。そこで入力した値が次のmodule(上の例ではCustomFeed::Mixi)のconfigに上書きされます。何も入力しなければ上書きしません(CustomFeed::Mixiでの値がデフォルト値となります)。promptが指定されている場合、その文字列は入力待ちに入る直前に標準エラー出力に印字されます。
ReadPasswordはReadLineのエコーバック無し版です。
気になること
- 既に同じようなモジュールがあるかも知れません(致命的)。
- 各Pluginのconfは独立しているため、$context->{plugins}を引っ張ってきて変なことをしています。
- 適切なカテゴリが見つからなかったため、Plagger::PluginにCustomConfigを掘ってます。
- CustomConfigのconfigを「password: ReadPassword」みたいな感じにしたかったのですが、設定キーが"password"を含んでいると、Plagger::Plugin#do_walk,Plagger#rewrite_configによって書き換えられてしまうため、少し直感的ではない設定方法にしています。
- テストを書いていません。
ソース(*.pmのみ抜粋)
Plagger/Plugin/CustomConfig.pm
package Plagger::Plugin::CustomConfig; use strict; use warnings; use version; our $VERSION = qv( (qw$Revision: 190 $)[1] / 1000 ); use Carp; use English qw(-no_match_vars); use UNIVERSAL::require; use base qw(Plagger::Plugin); sub register { my ( $self, $context ) = @_; $context->register_hook( $self, 'plugin.init' => \&init ); return; } sub init { my ( $self, $context ) = @_; foreach my $i ( 0 .. @{ $context->{plugins} } ) { if ( ref $context->{plugins}->[$i] ne __PACKAGE__ ) { next; } $i++; my $plugin = $context->{plugins}->[$i]; # $plugin is the next plugin. foreach my $ref ( @{ $self->conf } ) { my $module = __PACKAGE__ . q{::} . ( keys %{$ref} )[0]; my $config = ( values %{$ref} )[0]; $module->require or croak $EVAL_ERROR; my $value = $module->run($config); if ( defined $value ) { $plugin->conf->{ $config->{name} } = $value; } } } return; } 1;
Plagger/Plugin/CustomConfig/ReadLine.pm
package Plagger::Plugin::CustomConfig::ReadLine; use strict; use warnings; use version; our $VERSION = qv( (qw$Revision: 190 $)[1] / 1000 ); use English qw(-no_match_vars); use Term::ReadKey; sub run { my ( $class, $config ) = @_; if ( exists $config->{prompt} ) { print {*STDERR} $config->{prompt}; } my $value; eval { $value = ReadLine(0); chomp $value; }; if ($EVAL_ERROR) { return; } return $value; } 1;
Plagger/Plugin/CustomConfig/ReadPassword.pm
package Plagger::Plugin::CustomConfig::ReadPassword; use strict; use warnings; use version; our $VERSION = qv( (qw$Revision: 190 $)[1] / 1000 ); use English qw(-no_match_vars); use Term::ReadKey; sub run { my ( $class, $config ) = @_; if ( exists $config->{prompt} ) { print {*STDERR} $config->{prompt}; } my $value; eval { ReadMode('noecho'); $value = ReadLine(0); chomp $value; }; ReadMode(0); if ($EVAL_ERROR) { return; } return $value; } 1;