金がないので MacBook という名前になった最初の白いやつを長年使ってるんですが、一度ファンを交換したにもかかわらずまたファンの音がおかしくなってきています。もう一度交換すればいいんじゃないのという感じもするけど、
http://gameport.ocnk.net/product/134
を見ると6000円。5年間使ったマシンのパームレストが割れるリスクと6000円を投じて静音化とかちょっと考えたくないです。
あと電池も交換しました。これは非純正にもかかわらず明らかに金型が同じものを円高に物を言わせて DealExtreme.com で $48 程度で購入しました。DealExtreme.com は発送が遅い以外は大変安く送料もだいたい無料だし PayPal も使えて安心便利なので、ゴミを購入するときにはぜひ使うといいと思います。ただこの電池、普通につかってるだけで突然電源が落ちたりするし、微妙につくりがわるくそのうち外れそうです。8ヶ月で壊れたという残念なレビューもありましたし、今みるとちょっと容量のでかいやつが $38.90 で売ってるし大変ファックですね。
ここまでして今の MacBook を使ってるのは金のこともありますが、tumblr ステッカーがもったいないというのもあるし新しい tumblr ステッカーもほしいですね。Tumblr ステッカー欲しい!?


my @msgs = reverse (@{$twit->replies}, @{$twit->friends_timeline});
for my $nickname (@nicknames) {
if (($text =~ s/^\@$nickname//) || (
($msg->{in_reply_to_screen_name})
&& ($msg->{in_reply_to_screen_name} eq $nickname)
)) {
return $text;
}
}
fuba_recorder
fuba_recoder
fuba_recoder
fuba_ピカァァッ
フバコレ フバコレ
フバレコ フバレコ
プパペポ
フバレコたん フバレコちゃん
フコレバ フコレバ
フコバレ フコバレ
フレコバ フレコバ
フレバコ フレバコ
フヴァレコ フヴァレコ
ふゔゃれこ ふびゃれきょ
フバ様のマシーン
トウモロコシ小麦粉レコーダー
フバリコーダー
fuba_recorder
/;
if ($text =~ /^(.*?)(?:毎回|全部)(?:録画|予約|(?:録|と)っといて)/) {
$keyword = $1;
$is_repeat = 1;
}
elsif ($text =~ /^(.*?)(?:(?:、(?:なんとか)お願い)|(?:の|が|に)?(?:関する|出てる|録画|予約|(?:(?:で|出)る)?番組|(?:録|と)っといて))+/) {
$keyword = $1;
}
elsif (($text !~ /(飲|の)みたい/) && ($text =~ /^(.*?)(?:いつやるの|(?:が|を)?(?:見|み|観)たい)/)) {
$is_qa = 1;
$keyword = $1;
}
if ($m =~ /(?:(?:なに|なん|何)か)?(.*)(?:が|を)?(?:(?:(?:飲|の)(?:み|ま)|(?:た|食)べさ?|(?:喰|食|く)(?:い|わ))(?:た(?:い|く)|せ(?:ろ|て)))/) {
if (my $str = $1) {
if (server_avail($avail_dir, 'cookpad')) {
my $recipe = retrieve_keyword_cookpad($str);
if ($recipe) {
$new_message = join('、', @{$recipe->{ingredients}}).'とか買ってきて'.$recipe->{title}.'を作れ '.$recipe->{url};
}
else {
$new_message = '何か違うもの食べたほうがいいですよ';
}
}
else {
$new_message = '検索しすぎ';
}
}
}
elsif (my $boxing = text_boxing(
message => $m,
ngwords => \@ngwords
)) {
$new_message = $boxing->{dump_message};
}
elsif ($m =~ /ペプ|行動を?開始|ねる|ねむ|ねて|眠|おやすみ|寝|バタリ|スヤ|ネルソン/) {
$new_message = $goodnights[floor(rand(scalar(@goodnights)))];
}
elsif ($m =~ /黙れ/) {
$new_message = '...';
}
elsif ($m =~ /血が.*出る|失業|原君|痛い|進まない|ハァ|\\(^o^\)/|着る服が無い|あー|ねむい|鬱|ヘルプ|へるぷ|help|諦め|苦しい|つらい|希望がない|だめ|ダメ|駄目|死|しぬ|しにたい|自殺|たすけて|助けて|働きたくない|やだ|むり|無理|やめたい/) {
$new_message = $cheerups[floor(rand(scalar(@cheerups)))];
}
elsif ($m =~ /おめでと|やればできる|でかした|(?:えら|偉)い|お(?:疲|つか)れ|すごい|いい(?:です)?ね|ありがと|thx|サンクス|サンキュー|thank/) {
$new_message = $yourwelcomes[floor(rand(scalar(@yourwelcomes)))];
}
elsif ($m =~ /回|制限/) {
my $avail = server_avail($avail_dir, 'twitter_'.$req->{user});
$new_message = ($avail - 1);
}
if (!$new_message) {
if (int(rand(6))) {
my $disk = disk_rest();
if ($disk < 10) { # 10GB未満
$new_message = $dies[floor(rand(scalar(@dies)))];
}
elsif ($disk < 40) { # 40GB未満
$new_message = $noes[floor(rand(scalar(@noes)))];
}
else {
$new_message = $yeses[floor(rand(scalar(@yeses)))];
}
}
}
$req->{dump_message} = $new_message;
return $req;
}
if ($req->{message} =~ /^\[quiz\]/) {
if ($req->{message} =~ /\[\s+\]|次の選択肢/) {
$req->{is_quiz} = 1;
return $req;
}
}
if ($req->{is_quiz}) {
post('@'.$req->{user}.' '.answer_quiz(map {$_->{message}} @quiz[0..1], $ua), $mid);
}
if ($req->{too_many}) {
post('@'.$req->{user}.' 検索結果多すぎ、もうちょっと絞ってください', $mid);
}
elsif ($req->{is_forbidden}) {
post('@'.$req->{user}.' そのiepg偽物っぽい', $mid);
}
elsif ($req->{has_collision}) {
post('@'.$req->{user}.' '.$req->{collision_title}.'とかぶるのでむり', $mid);
}
elsif ($req->{is_expired}) {
post('@'.$req->{user}.' そのiepg古い', $mid);
}
elsif ($req->{is_qa}) {
if ($req->{url}) {
post('@'.$req->{user}.' '.$req->{keyword}.'、これはどうですか '.$req->{url}, $mid);
}
else {
post('@'.$req->{user}.' '.$req->{keyword}.'むり', $mid);
}
}
elsif ($req->{is_reserved}) {
if ($req->{keyword}) {
post('@'.$req->{user}.' '.$req->{keyword}.'、もう予約してる', $mid);
}
else {
post('@'.$req->{user}.' もう予約してる', $mid);
}
}
elsif ($req->{is_repeat}) {
if (grep {$req->{user} eq $_} @superusers) {
my $date = DateTime->from_epoch(epoch => $req->{repeat_expire});
my $hdate = $date->ymd('-');
post('@'.$req->{user}.' '.$req->{keyword}.'、'.$hdate.'まで全部録画します', $mid);
$refresh_repeat_flag = 1;
}
else {
post('@'.$req->{user}.' 金くれ', $mid);
}
}
elsif ($req->{default_iepg}) {
if ($req->{has_collision}) {
post('@'.$req->{user}.' '.$req->{collision_title}.'とかぶるからむり', $mid);
}
else {
post('@'.$req->{user}.' 予約した', $mid);
}
}
elsif ($req->{iepg}) {
my $justified_flag = ($req->{retrieve_result}->{justify}) ? 'とりあえず' : '';
post('@'.$req->{user}.' '.$req->{keyword}.'、'.$justified_flag.'これ予約した '.$req->{url}, $mid);
}
elsif ($req->{keyword}) {
if ($req->{search_result_num}) {
post('@'.$req->{user}.' '.$req->{keyword}.'むり、番組表にはあったけどなんかとかぶってる', $mid);
}
else {
post('@'.$req->{user}.' '.$req->{keyword}.'むり、検索にひっかかんない', $mid);
}
}
elsif ($req->{dump_message}) {
if ($req->{is_reply}) {
if (grep {$req->{user} eq $_} @uzaiuser) {
post('@'.$req->{user}.' '.$req->{dump_message}, $mid) if (int(rand(3)));
}
else {
post('@'.$req->{user}.' '.$req->{dump_message}, $mid);
}
}
if ($req->{is_boxer}) { # ボクサーの確率調整
post($req->{dump_message}, $mid) if (grep {$req->{user} eq $_} @boxeruser);
if (grep {$req->{user} eq $_} @boxeruser_light) {
post($req->{dump_message}, $mid) if (int(rand(3)));
next;
}
next if (grep {$req->{user} eq $_} @nguser);
if (grep {$req->{user} eq $_} @nguser_light) {
post($req->{dump_message}, $mid) unless (int(rand(20)));
next;
}
if (grep {$req->{user} eq $_} @nguser_strong) {
post($req->{dump_message}, $mid) unless (int(rand(50000)));
next;
}
post($req->{dump_message}, $mid) unless (int(rand(3)));
}
}
my @goodnights = qw/とっとと寝ろや 寝るな ぼくもねます 6時起きな/; my $goodmorning_notice = ( ( (localtime(time))[2] + 1 + 3 + int(rand(7)) ) % 12 ).'時起きな'; push @goodnights, $goodmorning_notice, $goodmorning_notice, $goodmorning_notice; my @yeses = qw/はい はいはい 了解しました そうですね/; my @noes = qw/むり めんどくせえ... ハァ〜 らめぇ はぁん はぁ? だるい/; my @dies = qw/死ぬ 助けて マジ無理 涅槃きれい… 川渡ってる/; my @cheerups = qw/ ぜんっぜん気持ち伝わってこない!もう1回! そんなんじゃ聞こえないよ!全っ然気持ちが伝わってこない! 引きずらない!切り替えていこう! がんばれがんばれできるできる絶対できるがんばれもっとやれるって!! ぜったいだいじょうぶだよ!なんとかなるよ! ぜったいだいじょうぶだよ! ぜったいなんとかなるよ! だいじょうぶだよ!ぜったいなんとかなるよ! /; my @yourwelcomes = qw/ どういたしまして はいはい いえいえ /;
sub text_boxing { my %opt = @_; my $m = $opt{message}; my $ngwords = $opt{ngwords}; return if (grep {my $ngword = $_; $m =~ /$ngword/} @$ngwords); $m =~ s/^(\@[^\s]+\s+)+//; my @arms = qw/= ≡ - - - - -=≡ ≡=- 〜/; push @arms, ''; my $arm = $arms[int(rand(scalar(@arms)))]; my $lnp = $arm.'o'; my @lpunches = ($lnp, $lnp, $lnp, $lnp, $lnp, '9', '9', 'ノ⧉'); my $lpunch = $lpunches[int(rand(scalar(@lpunches)))]; my $rnp = 'o'.$arm; my @rpunches = ($rnp, $rnp, $rnp, $rnp, $rnp, '6', '6', '⧉ヽ'); my $rpunch = $rpunches[int(rand(scalar(@rpunches)))]; my @lfaces = map {"(o'-')"} (0..6); push @lfaces, "o'-')"; push @lfaces, "イェイ! o'-')"; my $lface = $lfaces[int(rand(scalar(@lfaces)))]; my @rfaces = map {"('-'o)"} (0..6); push @rfaces, "('-'o"; push @rfaces, "('-'o イェイ!"; my $rface = $rfaces[int(rand(scalar(@rfaces)))]; my $result = { is_boxer => 0, dump_message => '', }; if ($m =~ s/^[^((\{]*[((\{]\s*\*?\s*(?:(?:´[・・])|(?:`[・・])|(?:கு)|[☉\'´ு``◕´◕゜^^・。◠著])/${lface}${lpunch})゜/) { $result->{dump_message} = $m; $result->{is_boxer} = 1; return $result; } if ($m =~ s/(?:(?:[・・]`)|(?:[・・]´)|(?:கு)|[\'`ு`◕゜☣\^◠=☉〓権≦])\s*\*?\s*[\}))][^))\}]*$/゜(${rpunch}${rface}/) { $result->{dump_message} = $m; $result->{is_boxer} = 1; return $result; } return; }
Gearmanを使い、
用に、2つのworkerを動作。
sub post_twit { my %opt = @_; delete $opt{twit}; delete $opt{ua}; my @workers = ($opt{worker}) ? ($opt{worker}) : ('localhost'); my $client = Gearman::Client->new; $client->job_servers(@workers); my $args = freeze(\%opt); my $result_ref; $result_ref = $client->dispatch_background("post_twit", \$args, {}); return $result_ref; }
投稿につかうGearman用のworker
use Gearman::Worker; use Storable qw(thaw); (snip) my $worker = Gearman::Worker->new; $worker->job_servers(@hosts); $worker->register_function( post_twit => sub { my $job = shift; my %opt = %{thaw($job->arg)}; my $text = $opt{message}; my $reply_id = $opt{reply_id}; my $tcss = $opt{tcss}; if ($opt{video_path}) { return 0 unless (-e $opt{video_path}); my $thumb_url = upload_thumbnail( $opt{video_path}, ($opt{tag} || ''), ); $text .= ' '.$thumb_url; } if (1 == int(rand(3))) { $text = convert($text, $tcss, $ua); } warn $text; my $args = { status => $text, }; $args->{in_reply_to_status_id} = $reply_id if (defined $reply_id); return ($twit->update($args)) ? 1 : 0; } ); $worker->work while 1;

WedataのText Conversion Servicesに登録されてるものをつかいます。

sub convert { my ($text, $tcss_ref, $ua) = @_; use HTTP::Status qw/:is/; my @tcss = @{$tcss_ref}; srand(time); if (@tcss) { my $id = ''; if ($text =~ s/^(\@\w+\s)//) { $id = $1 || ''; } my $url = ''; if ($text =~ s/(\shttp\:\/\/.*)$//) { $url = $1 || ''; } my $new_text; my $response; do { my $service = $tcss[floor(rand(scalar(@tcss)))]; my $surl = $service->{url}; warn $surl; my $text_esc = uri_escape( encode( ($service->{enc} || 'utf-8'), $text ) ); $surl =~ s/\%s/$text_esc/; if ($service->{xpath}) { $new_text = get_text_by_xpath($surl, $service->{xpath}, $ua, $service->{enc}); } else { $ua ||= LWP::UserAgent->new(); my $resp_local = $ua->get($surl); if (is_success($resp_local->code)) { $new_text = decode($service->{enc}, $ua->get($surl)->content); } } } while (!$new_text); $new_text =~ s/^\@/@/; $text = $id.$new_text.$url; warn $text; } return $text; }
sub retrieve_keyword { my ($keyword, $ua, $repeat) = @_; return unless $keyword; my $search_url = 'http://tv.goo.ne.jp/search/result.php?genres%5B%5D=&category=VU&key=' . uri_escape(encode('EUC-JP', $keyword)); my $tree = HTML::TreeBuilder::XPath::Remote->new_from_uri($search_url, $ua); my $number; my @number_nodes = $tree->findnodes('id("incontents")/p[@class="fs16"][1]'); if (@number_nodes) { my $text = $number_nodes[0]->as_text; $text =~ /\((\d+)件\)/; $number = $1 || 0; } return unless $number; my $xpath = '//table[@class="t01"]//a[contains(@href, "/contents/program")]'; $xpath .= '[count(./img) < 1]' if ($repeat); my @urls = $tree->findnodes($xpath); my @url_list; if (scalar(@urls)) { @url_list = map { $_->attr('href') } @urls; return { number => $number, list => \@url_list, }; } return; }
sub justify_keyword { my ($keyword, $ua) = @_; my $yahoo_search_url = 'http://search.yahoo.co.jp/search?ei=UTF-8&p=' . uri_escape(encode('utf-8', $keyword)); my $tree = HTML::TreeBuilder::XPath::Remote->new_from_uri($yahoo_search_url, $ua); my $text = ''; if (my @nodes = $tree->findnodes('id("web")/ol/li/a')) { $text = $nodes[0]->as_text; } $text =~ s/\[[^\]]+\]$//; return "$text"; }
sub retrieve_keyword_cookpad { my ($keyword, $ua) = @_; return unless $keyword; if (my @keywords = split(/と|の|で作る/, $keyword)) { $keyword = join ' ', @keywords; } my $search_url = 'http://cookpad.com/%E3%83%AC%E3%82%B7%E3%83%94/' . uri_escape(encode('utf-8', $keyword)); my $tree = HTML::TreeBuilder::XPath::Remote->new_from_uri($search_url, $ua); my $xpath = '//div[@class="recipe-preview"]//span[contains(@class, "title")]/a'; my $xpath_ing = '//div[@class="recipe-preview"]//div[contains(@class, "material")]'; my @urls = $tree->findnodes($xpath); my @ings_nodes = $tree->findnodes($xpath_ing); if (scalar(@urls)) { my $index = floor(rand(scalar(@urls))); my $url = $urls[$index]; my $ing = $ings_nodes[$index]->as_text; $ing =~ s/(\s| )+/ /g; $ing =~ s/^\s*材料://; my @ings = map {s/\s.*$//;$_} split /、/, $ing; @ings = (@ings > 3) ? @ings[0..2] : @ings; return { title => $url->as_text, url => $url->attr('href'), ingredients => \@ings, }; } return; }




それぞれ使用しています。
また、
それぞれ勝手に使用しています、すみません…
ありがとうございました。これからもfuba_recorderをよろしくお願いいたします。
GETだとAPI制限になることが判明したのでuserscripts.orgから引き上げたけど、とりあえずソースだけ貼っとく。いつものようにPOSTでAPI制限は無視できるので、使いたい人はそこいじって使えばいいとおもいます。もうPOSTでAPI制限は無視できなくなったので使わない方がいいですよ。
// ==UserScript== // @name Twitter favorites counter // @namespace http://fuba.moaningnerds.org/ // @include http://twitter.com/* // ==/UserScript== $X('//link[@rel="alternate"]')[0].href.match(/(\d+)/); var id = RegExp.$1; GM_xmlhttpRequest({ method: "GET", url: "http://twitter.com/users/show/" + id + ".xml", onload: function(x){ if (x.responseText.match(/<favourites_count>(\d+)<\/favourites_count>/)) { var span = document.createElement('span'); span.className = 'stat_count'; span.appendChild(document.createTextNode(RegExp.$1)); var link = $X('id("favorites_tab")')[0]; link.insertBefore(span, link.childNodes[0]); } } }); // simple version of $X // $X(exp); // $X(exp, context); // @source http://gist.github.com/3242.txt function $X (exp, context) { context || (context = document); var expr = (context.ownerDocument || context).createExpression(exp, function (prefix) { return document.createNSResolver(context)(prefix) || (document.contentType == "application/xhtml+xml") ? "http://www.w3.org/1999/xhtml" : ""; }); var result = expr.evaluate(context, XPathResult.ANY_TYPE, null); switch (result.resultType) { case XPathResult.STRING_TYPE : return result.stringValue; case XPathResult.NUMBER_TYPE : return result.numberValue; case XPathResult.BOOLEAN_TYPE: return result.booleanValue; case XPathResult.UNORDERED_NODE_ITERATOR_TYPE: // not ensure the order. var ret = [], i = null; while (i = result.iterateNext()) ret.push(i); return ret; } return null; }
他消火が伊露露モナコMeCab55二時へホンがツクる
ピャじゃなかった!なおした
最新版のMeCabがピプピョプです。
% wget http://nchc.dl.sourceforge.net/sourceforge/mecab/mecab-ipadic-2.7.0-20070801.tar.gz
% tar vxzf mecab-ipadic-2.7.0-20070801.tar.gz
% cd mecab-ipadic-2.7.0-20070801
% wget http://fuba.moaningnerds.org/src/papyopu/conv.pl
% perl conv.pl
% wget http://fuba.moaningnerds.org/src/papyopu/decode.pl
% exthtml.pl -x '//*[contains(@class, "entry-content")]' -p '$v=~s/^\s+//;$v' \
-n '//a[@rel="prev"]/@href' -d 2 http://twitter.com/youpy | perl decode.pl new
ポプペプ 国鉄
ポパポパペープ 露サモアセール
パンパポパ、プーパーペパッペピペペプペパ 南ア炉は、スーパーへ勝手に寝てくれた
ポンペンポポポピパ ホンレンゾ炉をした
プポップパプペンポペピポプパーペンパプピピュプポプポプポDVD プポピポパッパ ストップ安兼露米国バーゲンが無二十号棟のDVDクロキを待った
パプポパプペプッパ 他クロマツへ打った
ペピポポプポプペンプポンパ 米露露雨のフェンス飲んた
ピピポパパーポポプパポポピポピ シシコワカート&熊本市の日
パポプパピペ + パンポピープーパイ アコウダイへ+&ピープーパイ
ポピパ 5二課
パパピープ バカチーム
Handling パッパ Handlingだった
Handing ペピパ http://tinyurl.com/69slhd Handingへ二課http://tinyurl.com/69slhd
パペプピパ 加セルビア
ペッププピパピ セックス二課に
Gnip + twitter、URL ピパパピパパペッポプAPI パパパパピャピペパピ、パンパポ Gnip+twitter、URLに払いさが結構APIがマハラジャ妃へ去り、神田炉
ペポン 世論
-196 ペポプ -196ゼロ区
パプパププピポペパパピペパ ガスマスクにこれから云えば
Jピープパペパピ Jチームが粘り
ポプペプ 国鉄
パパペッパ 他が結果
ポペパプパペペペーポ 露ベラウが寝てメート
ポプパペパパペピパ 露グアテマラケニア
@jazzanova プンポピパ? @jazzanova群の二課?
パンペーパポン サンケーがぽん
ポピポプンパペッペピパポパ トリノ郡が決定がの他
ポーピー ローリー
プポパピッパ 角田一茶
プパパッパ クラかった
パッピュポペポプププ ラッシュ炉へ動物
ポペペーポ おめぇーも
@fub プポピ @fub強い
パンパポパピピパペパ 南ア露ハイチが寝た
ポパペププププポパピ 5課へグズグズ止まり
パパペッパ 他が結果
emobile ピプペンペペピプポパパ emobileに無レンゲへ行くのだが
ペパーピー ケラーリー
ポーピーパッペププ コーヒーだって打つ
ピュッピャ 出射
ペ え
ポプペプ 国鉄
パパパーポパポピパペププパペプパペプパプ 他アワードが呼び掛ける無差別が寝るある
プピプピー スミスリー
ポペンパパピ ごめんなさい
パイプップパプピ、パピプパパプポポパンパポパペンパピピペパ パイプップパプピ、加ビルマ加雨のロダンラボラ¥が二二ケタ
ピープ チーム
パプポンパン 各ソン・サン
ピパプ http://tinyurl.com/575vb3 にあるhttp://tinyurl.com/575vb3
ポプペプ 国鉄
@bulkneets ププピプポパピンピポピ @bulkneets無スミスホアキン氏の日
http://api.satoru.net/text2... http://api.satoru.net/text2...
プーポーピプポプパピンプポポピパポペポプ ウーホーピストルがピンクを呑みさを寝よう
ピパプ にある
プペペ グレて
ポンプポー 本部Ρ
パパペッペピパ バカ決定だ
プパい 歩がい
パポパピプパピポ サモアビルマ妃&
ポパパイパイ ポパパイパイ
まず、conv.plで学習済みipadicの見出し語を最近はやってるパ行に変換しています。そのあとdecode.plの中でMeCabを使って形態素解析を行い、素性列:元見出し語の変換を行うことでまともな日本語に変換しています。decode.plに突っ込むテキストはexthtml.plでTwitterのポプピーさんの発言からぶっこ抜いてきています。
ぜんぜんだめですね。まともだったころのポプピーさんの発言を大量に収集して、それを形態素解析&パ行に変換したものを学習用コーパスとして使用すると多少パピになるかもピペパペン。
ピペパペンと投げるのもアレだし、簡単なのならできるかなーと取れる範囲のログ全部とってやってみたものの、文脈無視して漢字の羅列になる始末でぜんぜんだめでした。形態素解析の学習データとしては何桁か文数が足らなかったのか、それともやりかたを間違えたのかよくわかんないけど、もうちょっと考える必要がありパプペ。