Skip to content
11月 20 13

ニコニコ動画ランキングの訪問済み動画の表示 (NicoRefRemover)

by wetcradle

訪問済みの動画なのに未訪問としてリンクが表示される

ニコニコ動画のランキングにおいて、
訪問済みの動画なのにリンクスタイルが未訪問の状態になっていることがあります。

これは、ランキング順位に応じて、リンク先 URL の ref= の値が以下のように変化するためです。

  • ?ref=ranking_video_top
  • ?ref=ranking_video_mid
  • ?ref=ranking_video_bot

訪問済みとして表示する Safari 機能拡張

毎日何度もランキングをチェックする自分としては、これは非常に不便だったため、
訪問済みの動画へのリンクをちゃんと訪問済みのスタイルで表示するための Safari 機能拡張を作成しました。

仕組みは簡単で、リンク末尾の ?ref= 以降を削除しているだけです。

NicoRefRemover.safariextz

9月 26 12

Twitter のツイート保存 (save_user_timeline.pl)

by wetcradle

以前紹介した save_user_timeline.pl ですが、Twitter の HTML を舐めていたので、Twitter の更新によって動かなくなっていました。
というわけで save_user_timeline.pl を現状に Twitter に対応させました。
ちなみに、cron に登録して、定期的にツイートを保存していくような用途を前提として考えています。

#!/usr/bin/perl

use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request;
use Date::Parse;
use HTML::TreeBuilder;
use Encode;
use JSON qw(decode_json);
use List::Util qw(max);

########## config ##########
my $TWITTER_URL = "http://twitter.com/";
my $DIR = "/path/to/save_dir";
my $RETRY_DELAY = 5;
my $RETRY_MAX_COUNT = 5;

########## main ##########
my $retry_count = 0;
main: {
	if ($#ARGV != 0) {
		die "Usage: $0 screen_name";
	}
	
	my $screen_name = $ARGV[0];
	if ($screen_name =~ /[^a-zA-Z0-9_]/) {
		die "illegal screen_name";
	}
	
	print STDERR "$screen_name\n";
	
	`mkdir -p $DIR`;
	
	my $proxy = new LWP::UserAgent;
	
	my $user_id = &get_user_id($TWITTER_URL, $screen_name, $proxy);
	print STDERR "($user_id)\t";
	
	my $post_hash = &load_saved_timeline($DIR, $user_id);
	
	my $add_sum = &load_timeline($screen_name, $post_hash, $proxy);
	print STDERR "($add_sum)\n";
	
	&save_timeline($DIR, $user_id, $post_hash);
}

########## save_timeline ##########
sub save_timeline($$) {
	my ($dir, $user_id, $post_hash) = @_;
	open(POSTS, ">$dir/$user_id") || die "open failed";
	foreach my $id (sort {$a <=> $b} keys %{$post_hash}) {
		my $post = $post_hash->{$id};
		print POSTS $post->{"id"},",",$post->{"time"},",",$post->{"screen_name"},",",$post->{"data"},"\n";
	}
	close(POSTS);
}

########## load_timeline ##########
sub load_timeline($$) {
	my ($screen_name, $post_hash, $proxy) = @_;
	my $last_id = max(keys %{$post_hash});
	my $add_sum = 0;
	my $max_id = undef;
	my $has_more_items = 1;
	TIMELINES: while ($has_more_items) {
		print STDERR ".";
		my $timeline_url = &get_timeline_url($screen_name, $max_id);
		my $req = HTTP::Request->new('GET' => $timeline_url);
		my $res = $proxy->request($req);
		if (!$res->is_success) {
			if ($res->code == 404) {
				die "not found";
			}
			&inc_retry_count() || last;
			next;
		}
		my $result = $res->content();
		my $json = decode_json($result);
		$has_more_items = $json->{"has_more_items"};
		my $items_html = $json->{"items_html"};
		
		my $tree = HTML::TreeBuilder->new;
		$tree->parse($items_html);
		my @tweet_divs = $tree->look_down("data-tweet-id", qr/.+/);
		if (!scalar(@tweet_divs)) {
			last;
		}
		foreach my $tweet_div (@tweet_divs) {
			my $post = {};
			$post->{"screen_name"} = $screen_name;
			my $retweet_id = $tweet_div->attr("data-retweet-id");
			$post->{"id"} =  $retweet_id || $tweet_div->attr("data-tweet-id");
			my ($time_span) = $tweet_div->look_down("data-time", qr/.+/);
			$post->{"time"} = $time_span->attr("data-time");
			my ($tweet_text_p) = $tweet_div->look_down("class", "js-tweet-text");
			my $data = encode('utf-8', $tweet_text_p->as_text);
			$data =~ s/(^ | $)//g;
			$post->{"data"} = $retweet_id ? "RT @" . $tweet_div->attr("data-screen-name") . ": " . $data : $data;
			$data =~ s/,/<comma>/g;
			$data =~ s/\r/<cr>/g;
			$data =~ s/\n/<lf>/g;
			if ($post->{"id"} <= $last_id) {
				last TIMELINES;
			}
			$post_hash->{$post->{"id"}} = $post;
			$max_id = $post->{"id"} - 1;
			$add_sum++;
		}
		$tree = $tree->delete;
	}
	return $add_sum;
}

########## load_saved_timeline ##########
sub load_saved_timeline($$) {
	my ($dir, $user_id) = @_;
	my %post_hash = ();
	if ( -e "$dir/$user_id" ) {
		open(POSTS, "<$dir/$user_id") || die "open failed";
		my @post_array = <POSTS>;
		close(POSTS);
		foreach my $line (@post_array) {
			chomp($line);
			my $post = {};
			($post->{"id"}, $post->{"time"}, $post->{"screen_name"}, $post->{"data"}) = split(/,/, $line);
			$post_hash{$post->{"id"}} = $post;
		}
	}
	return \%post_hash;
}

########## get_user_id ##########
sub get_user_id($$$) {
	my ($twitter_url, $screen_name, $proxy) = @_;
	my $request_url = $twitter_url.$screen_name;
	my $req = HTTP::Request->new('GET' => $request_url);
	my $res = $proxy->request($req);
	if (!$res->is_success) {
		if ($res->code == 404) {
			die "not found";
		}
		&inc_retry_count() || die "failed";
		next;
	}
	my $result = $res->content();
	#print $result;
	if (index($result, "class=\"protected-box\"") != -1) {
		die "protected user";
	}
	my $tree = HTML::TreeBuilder->new;
	$tree->parse($result);
	my ($profile_div) = $tree->look_down("class", "profile-card-inner");
	my $user_id = $profile_div->attr("data-user-id");
	$tree = $tree->delete;
	return $user_id;
}

########## get_timeline_url ##########
sub get_timeline_url($$) {
	my ($screen_name, $max_id) = @_;
	if (defined($max_id)) {
		return "http://twitter.com/i/profiles/show/$screen_name/timeline?include_available_features=1&include_entities=1&max_id=$max_id";
	}
	return "http://twitter.com/i/profiles/show/$screen_name/timeline?include_available_features=1&include_entities=1";
}

########## inc_retry_count ##########
sub inc_retry_count(){
	$retry_count++;
	if ($retry_count > $RETRY_MAX_COUNT) {
		warn "failed";
		return 0;
	}
	#warn "retry $retry_count";
	sleep($RETRY_DELAY);
	return 1;
}
4月 7 12

as3 用ロギングフレームワーク log4a (as3 版 log4j)

by wetcradle

as3 用のロギングフレームワークで納得の行くものが見つからなかったので、
as3 版 log4j、名付けて log4a を作ってみました。
log4j ほど複雑ではありません。

  • カテゴリ
  • レベル
  • フィルタ (独自の継承クラスを作成することで拡張可能)
  • レイアウト (独自の継承クラスを作成することで拡張可能)
  • アペンダ (独自の継承クラスを作成することで拡張可能)
  • クライアントとサーバに分離

使い方

log4j と似ているので、log4j の使い方を調べてください。

設定ファイル


<configuration>
	<appender name="console" class="com.wetcradle.log4a.appender.ConsoleAppender">
		<filter class="com.wetcradle.log4a.filter.LevelRangeFilter">
			<param name="levelMin" value="INFO"/>
			<param name="levelMax" value="ERROR"/>
		</filter>
	</appender>
	<appender name="file" class="com.wetcradle.log4a.appender.air.RollingFileAppender">
		<param name="file" value="/Users/kubota/Desktop/test.log"/>
		<param name="maxFileSize" value="100"/>
		<layout class="com.wetcradle.log4a.layout.PatternLayout"/>
	</appender>
	<category name="LoggingSample" additivity="true">
		<level value="DEBUG"/>
		<appender-ref ref="file"/>
	</category>
	<root>
		<level value="INFO"/>
		<appender-ref ref="console"/>
	</root>
</configuration>

as3

package {
	
	import com.wetcradle.log4a.LogClient;
	import com.wetcradle.log4a.appender.air.ConfigurableAirAppender;
	import com.wetcradle.log4a.config.XMLConfigurator;
	import com.wetcradle.log4a.server.DefaultLogServer;
	import flash.display.MovieClip;
	
	public class LoggingSample extends MovieClip {
		
		// Air 用アペンダクラスのロード
		ConfigurableAirAppender;
		
		private static var log:LogClient = new LogClient(LoggingSample);
		
		// 設定ファイル
		[Embed(source="log4a.xml", mimeType="application/octet-stream")]
		private var log4aXML:Class;
		
		public function LoggingSample():void {
			super();
			
			configLogServer();
			
			log.debug("this");
			log.info("is");
			log.warn("a");
			log.error("test");
			log.fatal(":)");
		}
		
		private function configLogServer():void {
			var xmlFileConfigurator:XMLConfigurator = new XMLConfigurator(DefaultLogServer.defaultLogServer);
			xmlFileConfigurator.parseConfiguration(new XML(new log4aXML()));
		}
		
	}
}

ダウンロード

ソースコードはコメントほとんど入れてないです。ごめんなさい。
それと、ライブラリ適当に変えていくのでバージョン間に互換性はあんま無いです。

lib.20120407.tar

9月 15 11

IPhoneBadge.as (iPhone 風のバッジ)

by wetcradle

iPhone や Lion のあのバッジを as3 で実装しました。

  • サイズの調整は height プロパティで行います。width は自動的に設定されます。
  • 文字スタイルと背景色を変更可能

サンプル

使い方

package {
	
	import com.wetcradle.display.IPhoneBadge;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.text.TextFormat;
	
	public class IPhoneBadgeSample extends MovieClip {
		
		private var badge:IPhoneBadge;
		
		public function IPhoneBadgeSample():void {
			super();
			
			badge = new IPhoneBadge();
			//badge.textFormat = new TextFormat("Helvetica", 17, 0xffffff);
			//badge.color = 0xff0000; // 背景色
			//badge.height = 28; // サイズ調整は height にて行う
			badge.x = badge.y = 10;
			badge.count = 1;
			addChild(badge);
			
			addEventListener(Event.ENTER_FRAME, enterFrameHandler);
		}
		
		private function enterFrameHandler(e:Event):void {
			badge.count = Math.max(1, badge.count + Math.ceil(badge.count / 20));
		}
		
	}
}

ダウンロード

ソースコードはコメントほとんど入れてないです。ごめんなさい。
それと、ライブラリ適当に変えていくのでバージョン間に互換性はあんま無いです。

lib.20110915.tar.gz

6月 4 11

改行コードを調べる newline_code.pl

by wetcradle

ファイルの改行コードを確認しなければいけないことが結構あります。

od や xxd で調べてもいいのですが、面倒臭いし、混在しているかどうかが分かりません。また、nkf –guess を使ってもいいのですが、バージョンによっては出力されないみたいです。

ということで、簡単なスクリプトですが、地味に便利かなと思って作りました。

使い方

$ ./newline_code.pl test/*txt
test/cr.txt	CR
test/crlf.txt	CRLF
test/empty.txt	UNKNOWN
test/lf.txt	LF
test/mix.txt	MIXED NL

ソースコード

#!/usr/bin/perl

use strict;
use warnings;
use File::Basename;

########## config ##########

my $SCRIPT = basename($0);

my $CR = "CR";
my $LF = "LF";
my $CRLF = "CRLF";
my $MIXED_NL = "MIXED NL";
my $UNKNOWN = "UNKNOWN";

########## usage ##########
sub usage() {
	print STDERR <<EOF;
Usage: $SCRIPT &#91; file ... &#93;
       $SCRIPT < file

標準入力または複数ファイルの改行コードを調べます。
EOF
}

########## main ##########
if ($#ARGV == -1) {
	print &check_newline_code(*STDIN) . "\n";
}
else {
	foreach my $file (@ARGV) {
		open(FILE, "<$file") || die "open failed: $file: $!";
		print "$file\t" . &check_newline_code(*FILE) . "\n";
		close(FILE);
	}
}

########## check_newline_code ##########
sub check_newline_code($) {
	my ($input) = @_;
	my $lf_flag = 0;
	my $cr_flag = 0;
	my $crlf_flag = 0;
	my $previous_cr_flag = 0;
	while (!eof($input) && $lf_flag + $cr_flag + $crlf_flag <= 1) {
		my $byte = getc($input);
		if ($byte eq "\r") {
			if ($previous_cr_flag) {
				$cr_flag = 1;
			}
			$previous_cr_flag = 1;
		}
		elsif ($byte eq "\n") {
			if ($previous_cr_flag) {
				$crlf_flag = 1;
				$previous_cr_flag = 0;
			}
			else {
				$lf_flag = 1;
			}
		}
		else {
			if ($previous_cr_flag) {
				$cr_flag = 1;
				$previous_cr_flag = 0;
			}
		}
	}
	$cr_flag = 1 if ($previous_cr_flag);
	
	my $sum = $lf_flag + $cr_flag + $crlf_flag;
	if ($sum == 0) {
		return $UNKNOWN;
	}
	elsif ($sum > 1) {
		return $MIXED_NL;
	}
	elsif ($cr_flag) {
		return $CR;
	}
	elsif ($lf_flag) {
		return $LF;
	}
	elsif ($crlf_flag) {
		return $CRLF;
	}
}
6月 2 11

unicode2utf8.pl と utf82unicode.pl

by wetcradle

Unicode から UTF-8 への変換と、UTF-8 から Unicode への変換を行うスクリプトです。
一時的に必要になったので、やっつけ仕事。

unicode2utf8.pl

実行例

$ ./unicode2utf8.pl 65e5 672c 8a9e
string: 日本語
bytes (decimal): 230 151 165 230 156 172 232 170 158
bytes (hex): e6 97 a5 e6 9c ac e8 aa 9e
bytes (binary): 11100110 10010111 10100101 11100110 10011100 10101100 11101000 10101010 10011110
chars (decimal): 15112101 15113388 15248030
chars (hex): e697a5 e69cac e8aa9e
chars (binary): 111001101001011110100101 111001101001110010101100 111010001010101010011110

ソースコード

#!/usr/bin/perl

use strict;
use warnings;
use Getopt::Long;
use File::Basename;

########## usage ##########
sub usage() {
	my $script = basename($0);
	print STDERR <<EOF;
Usage: $script hex_unicode ...
       $script -d decimal_unicode ...
       $script -h
EOF
}

########## option ##########
sub parse_option() {
	my $decimal_mode = 0;
	my $help = 0;
	GetOptions (
		'decimal|d' => \$decimal_mode,
		'help|h' => \$help,
	) || (&usage && exit 1);
	
	if ($help) {
		&usage();
		exit 0;
	}
	
	if ($#ARGV == -1) {
		&usage();
		exit 1;
	}
	return $decimal_mode;
}

########## main ##########
sub main() {
	my $decimal_mode = &parse_option();
	
	my @utf8s = ();
	my @bytes = ();
	foreach (@ARGV) {
		my $unicode = $decimal_mode ? $_ : hex($_);
		my ($utf8, $bytes_ref) = &unicode2utf8($unicode);
		push(@utf8s, $utf8);
		push(@bytes, @$bytes_ref);
	}
	
	print "string: " . pack("C*", @bytes) . "\n";
	
	my $bytes_length = $#bytes + 1;
	printf("bytes (decimal):".(" %d" x $bytes_length)."\n", @bytes);
	printf("bytes (hex):".(" %02x" x $bytes_length)."\n", @bytes);
	printf("bytes (binary):".(" %08b" x $bytes_length)."\n", @bytes);
	
	my $utf8s_length = $#utf8s + 1;
	printf("chars (decimal):".(" %d" x $utf8s_length)."\n", @utf8s);
	printf("chars (hex):".(" %x" x $utf8s_length)."\n", @utf8s);
	printf("chars (binary):".(" %b" x $utf8s_length)."\n", @utf8s);
}
&main;

########## unicode2utf8 ##########
sub unicode2utf8($) {
	my ($unicode) = @_;
	
	# 変換
	# bytes は 実際の UTF-8 バイト列とは逆順なので注意
	my @bytes = (0, 0, 0, 0, 0, 0);
	if ($unicode <= -1) {
		die "invalid unicode";
	}
	elsif ($unicode <= 0x7f) {
		$bytes&#91;0&#93; = $unicode;
	}
	elsif ($unicode <= 0x7ff) {
		$bytes&#91;0&#93; = 0b10000000 | 0b111111 & $unicode;
		$bytes&#91;1&#93; = 0b11000000 | 0b11111 & $unicode >> 6;
	}
	elsif ($unicode <= 0xffff) {
		$bytes&#91;0&#93; = 0b10000000 | 0b111111 & $unicode;
		$bytes&#91;1&#93; = 0b10000000 | 0b111111 & $unicode >> 6;
		$bytes[2] = 0b11100000 | 0b1111 & $unicode >> 12;
	}
	elsif ($unicode <= 0x1fffff) {
		$bytes&#91;0&#93; = 0b10000000 | 0b111111 & $unicode;
		$bytes&#91;1&#93; = 0b10000000 | 0b111111 & $unicode >> 6;
		$bytes[2] = 0b10000000 | 0b111111 & $unicode >> 12;
		$bytes[3] = 0b11110000 | 0b111 & $unicode >> 18;
	}
	elsif ($unicode <= 0x3ffffff) {
		$bytes&#91;0&#93; = 0b10000000 | 0b111111 & $unicode;
		$bytes&#91;1&#93; = 0b10000000 | 0b111111 & $unicode >> 6;
		$bytes[2] = 0b10000000 | 0b111111 & $unicode >> 12;
		$bytes[3] = 0b10000000 | 0b111111 & $unicode >> 18;
		$bytes[4] = 0b11111000 | 0b11 & $unicode >> 24;
	}
	elsif ($unicode <= 0x7fffffff) {
		$bytes&#91;0&#93; = 0b10000000 | 0b111111 & $unicode;
		$bytes&#91;1&#93; = 0b10000000 | 0b111111 & $unicode >> 6;
		$bytes[2] = 0b10000000 | 0b111111 & $unicode >> 12;
		$bytes[3] = 0b10000000 | 0b111111 & $unicode >> 18;
		$bytes[4] = 0b10000000 | 0b111111 & $unicode >> 24;
		$bytes[5] = 0b11111100 | 0b1 & $unicode >> 30;
	}
	else {
		die "invalid unicode";
	}
	
	# utf8 の作成
	my $utf8 = 0;
	for (my $i=0; $i<=$#bytes; $i++) {
		$utf8 |= $bytes&#91;$i&#93; << ($i * 8)
	}
	
	# bytes から不要なバイトを除き、実際の UTF-8 バイト列に並び替える(若いインデックスが早いバイト)
	while ($#bytes > 0 && $bytes[$#bytes] == 0) {
		pop(@bytes);
	}
	@bytes = reverse(@bytes);
	
	return ($utf8, \@bytes);
}

utf82unicode.pl

実行例

$ ./utf82unicode.pl e6 97 a5 e6 9c ac e8 aa 9e
string: 日本語
unicodes (decimal): 26085 26412 35486
unicodes (hex): 65e5 672c 8a9e
unicodes (binary): 110010111100101 110011100101100 1000101010011110

ソースコード


#!/usr/bin/perl

use strict;
use warnings;
use Getopt::Long;
use File::Basename;

########## const ##########
my @HEAD_DATA_MASKS = (
undef,
0b01111111,
0b00011111,
0b00001111,
0b00000111,
0b00000011,
0b00000001,
);
my $TAIL_DATA_MASK = 0b00111111;

########## usage ##########
sub usage() {
my $script = basename($0);
print STDERR < \$decimal_mode,
‘help|h’ => \$help,
) || (&usage && exit 1);

if ($help) {
&usage();
exit 0;
}

if ($#ARGV == -1) {
&usage();
exit 1;
}
return $decimal_mode;
}

########## main ##########
sub main() {
my $decimal_mode = &parse_option();

my @bytes = map {
my $byte = $decimal_mode ? $_ : hex($_);
if ($byte < 0 || $byte > 0xff) {
die “invalid byte: $_”;
}
$byte;
} @ARGV;

my $counter = 0;
my $byte;
my $unicode;
my @unicodes = ();
my @temp_bytes = @bytes;
while ($byte = shift(@temp_bytes)) {
if ($counter == 0) {
$counter = &head_byte2byte_length($byte);
die “invalid byte: $byte” if !$counter;
$unicode = $HEAD_DATA_MASKS[$counter] & $byte;
}
elsif (&is_tail_byte($byte)) {
$unicode = ($unicode << 6) | ($TAIL_DATA_MASK & $byte); } else { die “invalid byte: $byte”; } push(@unicodes, $unicode) if (!(–$counter)); } if ($counter) { die “incomplete bytes”; } print “string: ” . pack(“C*”, @bytes) . “\n”; my $unicodes_length = $#unicodes + 1; printf(“unicodes (decimal):”.(” %d” x $unicodes_length).”\n”, @unicodes); printf(“unicodes (hex):”.(” %02x” x $unicodes_length).”\n”, @unicodes); printf(“unicodes (binary):”.(” %08b” x $unicodes_length).”\n”, @unicodes); } &main; ########## is_tail_byte ########## sub is_tail_byte($) { my ($byte) = @_; return (0b11000000 & $byte) == 0b10000000; } ########## head_byte2byte_length ########## sub head_byte2byte_length($) { my ($byte) = @_; if ((0b10000000 & $byte) == 0b00000000) { return 1; } elsif ((0b11100000 & $byte) == 0b11000000) { return 2; } elsif ((0b11110000 & $byte) == 0b11100000) { return 3; } elsif ((0b11111000 & $byte) == 0b11110000) { return 4; } elsif ((0b11111100 & $byte) == 0b11111000) { return 5; } elsif ((0b11111110 & $byte) == 0b11111100) { return 6; } return 0; } [/perl]

5月 31 11

TwitterGraph 1.3.4 公開

by wetcradle

TwitterGraph の 1.3.4 を公開しました。
http://twittergraph.wetcradle.com/

主な変更点

  • 共通のフォローをより検出するように改善
  • ステージのドラッグ中にノードのアニメーションを停止するように変更
  • ノード全体が移動していかないように、1つのノードが固定されるように変更
  • ノードのアニメーションのパラメータ調整
  • Flash サイドの使用ライブラリを独自ライブラリに統一
  • サーバサイドのスクリプトがひどかったので作り直し
  • API の消費許容数の向上

最も大きな変更点は「共通のフォローをより検出するように改善」です。
以前は statuses/friends API で取得されるフォロー関係(100 フォロー/リクエストまで、ユーザ情報あり)のみ表示していましたが、今回 friends/ids API (5000 フォロー/リクエストまで、ユーザ情報なし)と組み合わせることでフォロー関係を多く検出できるようにしました。

5月 28 11

ライフハッカーの全文配信化 (filterss.rb)

by wetcradle

以前、ITmedia と クラウド Watch の全文配信 RSS を紹介しましたが、ライフハッカーも全文配信したくなったので filterss.rb に設定を追加しました。全文配信は http://temp.wetcradle.com/filterss/lifehacker.rss で行っています。

filterss.rb 追加機能

ただ、ライフハッカーの全文には広告が埋めこまれているため、今までの filterss.rb では広告も配信してしまいます。そこで、filterss.rb のフィルタリング機能に特定要素を取り除く機能を追加しました。以下のような感じでフィルタリングルールを設定すれば OK です。

<rule>
	<block>
		<target>item_title</target>
		<regexp>^AD:</regexp>
	</block>
	<block>
		<target>item_title</target>
		<regexp>^PR:</regexp>
	</block>
	<extract>
		<target>item_page</target>
		<value>.entry_body</value>
	</extract>
	<remove>
		<target>item_page</target>
		<value>.EntryMoreBanner</value>
	</remove>
	<remove>
		<target>item_page</target>
		<value>.recententries</value>
	</remove>
	<remove>
		<target>item_page</target>
		<value>#newzia_connect_iframe</value>
	</remove>
	<remove>
		<target>item_page</target>
		<value>.ad_entry_amazon_under</value>
	</remove>
	<remove>
		<target>item_page</target>
		<value>.facebook_block</value>
	</remove>
	<remove>
		<target>item_page</target>
		<value>.rakuten_widget</value>
	</remove>
	<remove>
		<target>item_page</target>
		<value>.amazon_ranking</value>
	</remove>
</rule>

filterss.rb の配布

恥ずかしいので公開していませんが、要望があればいつでも公開します。

3月 23 11

FocusRotation (自作 Flash ライブラリの紹介)

by wetcradle

タブキーによるフォーカスの巡回を定義します。

  • FocusRotation を入れ子にすることができ、入れ子による木構造は1つの巡回を構成
  • 以下のメンバはフォーカスがスキップされる
    • UIComponent であり、enabled プロパティが false のメンバ
    • InteractiveObject であり、stage プロパティが null のメンバ
  • ユーザ操作によりフォーカスの入った FocusRotation が自動的にアクティブなものとなる

サンプル

以下のサンプルでは、A を根とするものと B を根とするもので、2つの木構造を構成しています。
F1 は enabled が false となっているのでスキップされます。

使い方

package {
	
	import com.wetcradle.focus.FocusRotation;
	import flash.display.MovieClip;
	
	public class FocusRotationSample extends MovieClip {
		
		public function FocusRotationSample():void {
			super();
			
			var focusRotationA:FocusRotation = new FocusRotation();
			focusRotationA.members = [a1, a2, a3];
			
			var focusRotationF:FocusRotation = new FocusRotation();
			focusRotationF.members = [f1, f2];
			
			var focusRotationD:FocusRotation = new FocusRotation();
			focusRotationD.members = [d1, d2];
			
			var focusRotationC:FocusRotation = new FocusRotation();
			focusRotationC.members = [focusRotationD, c1];
			
			var focusRotationB:FocusRotation = new FocusRotation();
			focusRotationB.members = [focusRotationC, b1, focusRotationF];
			
			focusRotationC.focusFirst();
		}
		
	}
}

ダウンロード

ソースコードはコメントほとんど入れてないです。ごめんなさい。
それと、ライブラリ適当に変えていくのでバージョン間に互換性はあんま無いです。

lib.20110323.tar.gz

3月 5 11

TextDateSelector (自作 UIComponent の紹介)

by wetcradle

日付の編集を行うコンポーネントです。気が向いたらカレンダーを表示して選択できる機能も追加します。

  • deleteButton をクリックすると defined プロパティが false になります。
  • もちろん、スタイル変更可能

サンプル

使い方

package {
	
	import com.wetcradle.ui.date.TextDateSelector;
	import flash.display.MovieClip;
	import flash.events.Event;
	
	public class TextDateSelectorSample extends MovieClip {
		
		private var textDateSelector:TextDateSelector;
		
		public function TextDateSelectorSample():void {
			super();
			
			textDateSelector = new TextDateSelector();
			textDateSelector.move(10, 10);
			textDateSelector.setSize(210, 22);
			//textDateSelector.enabled = false;
			textDateSelector.yearUnit = "年";
			textDateSelector.monthUnit = "月";
			textDateSelector.dateUnit = "日";
			textDateSelector.setDate(2011, 3, 5, true);
			textDateSelector.addEventListener(Event.CHANGE, changeHandler);
			addChild(textDateSelector);
		}
		
		private function changeHandler(e:Event):void {
			trace(textDateSelector.year, textDateSelector.month, textDateSelector.date, textDateSelector.defined);
		}
		
	}
}

ダウンロード

ソースコードはコメントほとんど入れてないです。ごめんなさい。
それと、ライブラリ適当に変えていくのでバージョン間に互換性はあんま無いです。

lib.20110305.tar.gz