あたらしものずきっ!

試してみたものとか、遊んでみたものを色々記してみます。

AirStationの設定をValueDomainに定期的につっこむ

AirStation WHR-HP-GNという前提での、ValueDomain定期更新スクリプト。各AirStationの型番毎にqueryが判明すれば汎用化できるんだろうけど、そこまでやる意味があるか分からないので。

AirStationにもAPI備わってればいいのになぁとはよくおもう。

#!/usr/local/bin/perl
use strict;
use warnings;
use Regexp::Common qw/net/;
use Encode qw(decode encode);
use WWW::Mechanize;
use URI;
use Net::DNS::ValueDomain::DDNS;

my $user = <id>;
my $pass = <pass>;
my $url  = "http://192.168.11.1/cgi-bin/cgi?";
my $ip   = '';

my $airstation = URI->new($url);

my $mech = WWW::Mechanize->new( autocheck => 1 );
$mech->credentials($user,$pass);
$airstation->query_form( req => 'twz' );
$mech->get( $airstation->as_string );
$airstation->query_form( req => 'tfr', id  => '41' );
$mech->get( $airstation->as_string );
$airstation->query_form( req => 'frm', frm => 'info.html' );
$mech->get( $airstation->as_string );

my $content = $mech->content;
my @content = split(/\n/, $content);
foreach my $line ( @content ) {
    $line =~ s/\s//g;
    if ( $ip eq '' && $line =~ /$RE{net}{IPv4}/o ) {
        $ip = encode('utf-8', $line);
    }
}
$ip =~ s/<td>//;
$airstation->query_form( req => 'twz', frm => 'logout.html' );
$mech->get( $airstation->as_string );

my $ddns = Net::DNS::ValueDomain::DDNS->new;
$ddns->update(
    domain   => 'haoyayoi.net',
    password => $ddns_pass,
    host     => '*',
    ip       => $ip,
);

簡単な掲示板というかフレームワークの設計をはじめてみた

色々な事情で機能縮小した掲示板を、縮小時の手間と変わらないままで、かつての機能を維持した上で、ユーザ情報をメッセージから分離させて管理できるようにする、という、ちょっと無茶っぽい条件を成立させるスクリプトの作成を勉強がてら行ってる。…使うかどうかは微妙だけど。

現状

  • 元々の掲示
  • 現在の掲示
    • ソースについては、現在編集ができる立場にいるためか伺い知る事はできる。とりあえず、テーブル設計や諸処のロジック設計から、拡張した後の手間が大きく増えるのだけは分かっている。

掲示板を一から設計したことがないのもあって、とりあえずアプリのベースを作り、そこに掲示板として必要な機能を突っ込んでいくことにした。PSYRENなる同類アプリも書いてたけど、本質的ではない部分で色々悩んだ挙句一旦停止した。

cgiとして処理をするしかない環境のため、コストパフォーマンスのいいモジュールということで cgi-extlib-perl のモジュールに依存する形。

かつsql片を直使うためにDBIx::Skinnyをいれてみた。DBI使うほうが速度早いのは確かなんだけど、あえて設計面を採ってみた。

とりあえずの目標

アプリ追加時にテーブルの設計も平行というメタ的な処理を行うこと。なおかつ、利用者がperlユーザではないため、ブラウザ上からcgiとしてそれらの処理を実行できるようにするのが前提になる。

最終的には管理に関して全てを管理画面的なところから押さえられるようにする、というのが目標。インストールから設置、運営まで、全部。

archnameのこと

私製アプリを作ってる時に、cpanmを使ってモジュールを非root権限にて入れておく作業をたまに行うのだけれど、lib以下に収まる際の

などのサブディレクトリについて余り考えたことがなかったので、確認してみた。

これはオペレーションシステムのアーキテクチャ依存のモジュールが収まる場所であり、OSXのシステムに依存するものであれば、darwin-2level以下にモジュールがインストールされるようになっている。

現在使用しているアーキテクチャ名が何かを確認したい場合は、

#!/usr/local/bin/perl
use strict;
use warnings;
use Config; 

print "$Config{archname}\n"; 

とかで。

アーキテクチャ依存モジュールの呼び出しを抽象化したい場合は、

BEGIN { unshift @INC, "/path/to/perl5/$Config{archname}"; }

ということになるけれど、各アーキテクチャ別にインストール作業しない場合は余り意味がないので、Configを使わずに直接パスを埋め込んだ方が早い。

CPAN::shellからcpanmにしてみた

CPAN::shellよりもcpanmのほうがイイヨイイヨ、と職場で教えられたので、さくらに導入してみた。確かに早い。CPAN::shellだと一日がかりだった作業がcpanmだと30分もしないうちにおわっちゃった。

つまづくかもしれないところ

テストにこけるモジュールは

cpanm -fl XML::Feed::RSS

と -fl 指定するくらい。

さくらインターネットにTokyoTyrantをいれてみる

TokyoTyrantを実際にさくらインターネット上で動かしてみようと思い、インストールしてみた。TokyoTyrantを入れる前に、予めTokyoCabinetを入れる必要があるため先に導入する。

TokyoCabinet

cd ~/tmp
wget http://1978th.net/tokyocabinet/tokyocabinet-1.4.44.tar.gz
tar xfz tokyocabinet-1.4.44.tar.gz
cd tokyocabinet-1.4.44
./configure --prefix=/home/haoyayoi/local
gmake
gmake install

TokyoTyrant

mkdir ~/local/sbin
cd ~/tmp
wget http://1978th.net/tokyotyrant/tokyotyrant-1.1.40.tar.gz
tar xfz tokyotyrant-1.1.40.tar.gz
cd tokyotyrant-1.1.40
./configure --prefix=/home/haoyayoi/local --with-tc=/home/haoyayoi/local --enable-static
gmake
gmake install

perl APIを入れる前に、ttservctlを動かす。ただ、そのまま実行しようとしてもこけるため、ttservctlを弄る。

  • ~/local/sbin/ttservctl
 prog="ttservctl"
 cmd="ttserver"
-basedir="/var/ttserver"
+basedir="/home/haoyayoi/var/ttserver"
 port="1978"
cd
local/sbin/ttservctl start

API for Perl

wget http://1978th.net/tokyotyrant/perlpkg/tokyotyrant-perl-1.16.tar.gz
tar xfz tokyotyrant-perl-1.16.tar.gz
cd tokyotyrant-perl-1.16
make && make test
make install

はまったこと

  • makeではなくgmakeが必要なこと
  • TokyoTyrantの configure で --with-tc オプションが必要だったこと
  • localディレクトリ以下にsbinディレクトリがなかったため、ttservctlがなくてperl APIがはいらなかった
  • ttservctlの利用する一時ディレクトリが権限でこけてた

壁紙スクレイピングなどしてみた

Galge.comが更新停止、というつぶやきをTwitterでみかけて、そんなにすぐに配布停止になるとは思えないけど、忘れた頃に…、というのは避けたかったので、壁紙をスクレイピングでダウンロードしてた。

#!/usr/local/bin/perl
use warnings;
use strict;
use LWP::UserAgent;
use URI;
use Web::Scraper;
use Time::HiRes;
use Path::Class qw/file/;

my $TimeSpan = 10.0;
my $galge_web = "http://www.galge.com/galge/nomember/sbp/wallpaper/index.html";
my $wp_dir = $ENV{'HOME'}."/Pictures/galge/";

my $scrap_home = scraper {
    process '//div[@id="indexmonth"]//li[last()]/a', 'link[]' => '@href';
};
my $year_res = $scrap_home->scrape( URI->new($galge_web) );
for my $year_link (@{$year_res->{link}}) { 
    warn $year_link;
    my $year_home = scraper {
        process '//table[@class="txt12k"]//tr[1]//td[4]/a', 'link[]' => '@href';
    };
    my $month_res = $year_home->scrape( URI->new($year_link) );
    Time::HiRes::sleep($TimeSpan);
    
    for my $month_link (@{$month_res->{link}}) {
        warn $month_link;
        my $month_home = scraper {
            process '//table[@class="txt12bldw"]/tr[1]//a', 'link[]' => '@href';
        };
        my $wp_res = $month_home->scrape( URI->new($month_link) );
        Time::HiRes::sleep($TimeSpan);
        
        for my $wp (@{$wp_res->{link}}) { 
            warn $wp;
            my @path_split = split(/\//, $wp);
            my $filename = $path_split[@path_split - 1];
            warn $filename;
            my $ua = LWP::UserAgent->new;
            my $path = file($wp_dir, $filename)->stringify;
            warn $path;
            $ua->get($wp, ":content_file" => $path);
            Time::HiRes::sleep($TimeSpan);
        }
    }
}

サーバの負担にならないようにと、アクセス毎に10秒間だけ間を開けてます。しょうもないことに全力を奮ったなぁと久々に思った。

menta用のpluginかきまくり

書きまくってる、という表現に値するほど書いてるとは思いません。でも、割と使い勝手はよくなると思います。

p5-menta-plugin

よくつかう処理をplugin化してコードを単純化させる、ということの繰り返しなんですが、へたに処理が入り込んだ状態でplugin化すると使い勝手が悪くなってしまうため、疎結合の良い練習になります。