rsync3で高速差分フルバックアップ
結局こうなった(現段階でのメモ)
CMD=/usr/local/bin/rsync STRAGE=/var/backup OLDEST=`date --date '7 days ago' +%Y%m%d` LATEST=`date --date '1 days ago' +%Y%m%d` for HOST in `ls $STRAGE`; do if [ -f $STRAGE/$HOST ] ; then continue fi HOSTNAME=`cat $STRAGE/$HOST/hostname.txt` echo "backup start : $HOSTNAME" if [ -d $STRAGE/$HOST/$OLDEST ] ; then rm -fr $STRAGE/$HOST/$OLDEST fi if [ -d $STRAGE/$HOST/current ] ; then mv $STRAGE/$HOST/current $STRAGE/$HOST/$LATEST fi $CMD -az --delete \ --link-dest="../$LATEST/" \ --rsync-path="sudo $CMD" \ --exclude-from=$STRAGE/$HOST/excludes.txt \ backup@$HOST:/ $STRAGE/$HOST/current/ done;
ローカルIPと同じ名称でディレクトリを作成すれば、バックアップ対象としてエントリされる仕組み。
以降は初期設定と、ターゲット毎の設定。
#------------------------- # 初期設定 #------------------------- scp backup.sh root@192.168.1.177: ssh root@192.168.1.177 ssh-keygen -t rsa useradd -G wheel backup passwd backup # rsync3 のインストール cd /usr/local/src/ wget http://rsync.samba.org/ftp/rsync/rsync-3.0.7.tar.gz tar xzfv rsync-3.0.7.tar.gz cd rsync-3.0.7 ./configure make make install #------------------------- # ターゲット毎の設定 #------------------------- ssh work@192.168.1.172 su - # rsync3 のインストール cd /usr/local/src/ wget http://rsync.samba.org/ftp/rsync/rsync-3.0.7.tar.gz tar xzfv rsync-3.0.7.tar.gz cd rsync-3.0.7 ./configure make make install # バックアップユーザの追加と sudo の設定 useradd backup visudo backup ALL= NOPASSWD:/usr/local/bin/rsync # 必要に応じて公開鍵認証を有効化する vi /etc/ssh/sshd_config RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys # バックアップサーバから公開鍵認証でログインできるようにする。 su - backup vi ~backup/.ssh/authorized_keys
rsync --link-dest --rsync-path など
覚書
HOST=192.168.1.172 CMD=/usr/local/bin/rsync OLDEST=`date --date '7 days ago' +%Y%m%d` LATEST=`date --date '1 days ago' +%Y%m%d` rm -fr $HOST/$OLDEST mv $HOST/current $HOST/$LATEST $CMD -narzv --delete \ --link-dest="../$LATEST/" \ --rsync-path="sudo $CMD" \ --exclude-from=excludes.txt \ / backup@$HOST:$HOST/current/
Twitter Search API の利用回数制限は秘密らしい
他のAPIの1時間に利用できる回数の制限は150回らしいのですが、検索に関しては非公開となっているようです。
ドキュメントの上のほうしか見てなくて、150回しか使えないと思ってたからなんか得した感じ。
Search API Rate Limiting
The Search API is rate limited by IP address. The number of search requests that originate from a given IP address are counted against the search rate limiter. The specific number of requests a client is able to make to the Search API for a given hour is not released. Note that the Search API is not limited by the same 150 requests per hour limit as the REST API. The number is quite a bit higher and we feel it is both liberal and sufficient for most applications. We do not give the exact number because we want to discourage unnecessary search usage.
150回以上使えるか確認用に作ったスクリプトはこれ
#!/usr/bin/perl use strict; use warnings; use LWP::UserAgent; use JSON; $!=1; for my $number (1..200) { my $query = "java"; my $ua = LWP::UserAgent->new; my $res = $ua->get("http://search.twitter.com/search.json?q=$query"); if($res->is_success){ my $json = from_json($res->content, {utf8 => 1}); if($json->{error}){ printf "%4d NG: %s\n", $number, $json->{error}; }else{ printf "%4d OK: %s results\n", $number, scalar(@{$json->{results}}); } }else { die $res->status_line; } }
HTML中のイメージのwidthを調整するフィルタの作りかけ
widthが無い場合やスタイルで指定されている場合、外部cssの場合など
対応できないので今は使わないことにした。
なんかもっといい方法ないかなぁ
#!/usr/bin/perl use strict; use warnings; use IO::File; use HTML::Parser; use Data::Dumper; my $file = 'test.html'; my $fh = new IO::File; $fh->open("< $file") or die "$!: $file"; my $str = join '', <$fh>; $fh->close; my $ret = img_resize($str); print "$ret\n"; sub _img_resize { my ($self, $tag, $attr, $attrseq, $text) = @_; return unless $tag eq 'img' && $attr->{'width'}; #print Dumper(\@_); $attr->{'width'} = int($attr->{'width'} * $self->{'ratio'}); my $attr_text = join ' ', map { sprintf '%s="%s"', $_, $attr->{$_} } grep !/height/, @$attrseq; $self->{'ret'} .= "<$tag $attr_text>\n"; }; sub img_resize { my $str = shift; my $p = HTML::Parser->new; $p->{'ratio'} = shift || '0.5'; $p->handler( start => \&_img_resize ); $p->handler( declaration => sub { return; $_[0]->{'ret'} .= "<!$_[1]>" } ); $p->handler( process => sub { return; $_[0]->{'ret'} .= $_[2] } ); $p->handler( comment => sub { return; $_[0]->{'ret'} .= "<!--$_[1]-->" } ); $p->handler( end => sub { return; $_[0]->{'ret'} .= $_[2] } ); $p->handler( text => sub { return; $_[0]->{'ret'} .= $_[1] } ); $p->parse($str); return $p->{'ret'}; };
JSONを取得してPerlオブジェクトのダンプとして見るワンライナー
覚え書きで
curl -s http://search.twitter.com/search.json?q=comlog \
perl -MJSON -MData::Dumper -nle 'print Dumper(from_json( $_, { utf8 => 1 } ));' | less |
Twitter Widget advanced search 対応版 なんてのないかなぁ
途中まで作っちゃったけど、探してみてないことに気づいた。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <meta http-equiv="Content-Script-Type" content="text/javascript" /> <title>sample1</title> <script type="text/javascript" src="jquery-1.4.2.js"></script> <script type="text/javascript" src="jquery.timer.js"></script> <script type="text/javascript"> kwd1 = encodeURI('ダウンタウン'); kwd2 = encodeURI('さんま'); $.getJSON('http://search.twitter.com/search.json?q=' + kwd1 + '+OR+' + kwd2 + '&rpp=100&callback=?', function(data) { $.each(data.results.reverse(), function(i, tweet){ $.timer(5000 * (i + 1), function(timer){ img = '<img src="' + tweet.profile_image_url + '" alt="' + tweet.from_user + '">'; $('div').prepend('<p>'+ '[' + ']' + img + decodeURI(tweet.text) + '</p>'); height = $('p:first').css('height'); $('p:first').css('margin-top', '-' + height).animate({marginTop : 0}, 'slow', 'linear'); timer.stop(); }); }); }); </script> <style type="text/css"> div { width: 500px; height: 400px; overflow: hidden; } </style> </head> <body> <div></div> </body> </html>