Tadashi Okoshi
slash****@users*****
2005年 10月 18日 (火) 18:49:06 JST
Index: affelio/apps/Mixi/extlib/WWW/Mixi.pm
diff -u affelio/apps/Mixi/extlib/WWW/Mixi.pm:1.4 affelio/apps/Mixi/extlib/WWW/Mixi.pm:1.5
--- affelio/apps/Mixi/extlib/WWW/Mixi.pm:1.4 Mon Aug 29 19:41:04 2005
+++ affelio/apps/Mixi/extlib/WWW/Mixi.pm Tue Oct 18 18:49:06 2005
@@ -4,7 +4,7 @@
use Carp ();
use vars qw($VERSION @ISA);
-$VERSION = sprintf("%d.%02d", q$Revision: 1.4 $ =~ /(\d+)\.(\d+)/);
+$VERSION = sprintf("%d.%02d", q$Revision: 1.5 $ =~ /(\d+)\.(\d+)/);
require LWP::RobotUA;
@ISA = qw(LWP::RobotUA);
@@ -76,8 +76,9 @@
if (not $res) { return "ページを取得できていません。"; }
elsif (not $res->is_success) { return sprintf('ページ取得に失敗しました。(%s)', $res->message); }
else {
+ my $re_attr = '(?:"[^"]+"|\'[^\']+\'|[^\s<>]+)\s+';
my $content = $res->content;
- return 0 if ($content !~ /<form[^<>]+action=["']?([^"'\s<>]*)["']?.*?>/);
+ return 0 if ($content !~ /<form (?:$re_attr)*action=("[^""]+"|'[^'']+'|[^\s<>]+)/);
return 0 if ($self->absolute_url($1) ne $self->absolute_url('login.pl'));
$self->{'mixi'}->{'next_url'} = ($content =~ /<input type=hidden name=next_url value="(.*?)">/) ? $1 : '/home.pl';
return "Login Failed ($1)" if ($content =~ /<b><font color=#DD0000>(.*?)<\/font><\/b>/);
@@ -233,17 +234,32 @@
my $base = $res->base->as_string;
my $content = $res->content;
my @items = ();
- if ($content =~ /<!-- start: お知らせ -->(.*?)<\/table>/s) {
+ if ($content =~ /<img src=[^ <>]+ ALT=お知らせ VSPACE=1 WIDTH=100 HEIGHT=37>.*?<table BORDER=0 CELLSPACING=0 CELLPADDING=0>(.*?)<\/table>/is) {
$content = $1;
- $content =~ s/[\r\n]//g;
+ $content =~ s/[\r\n]+//gs;
$content =~ s/<!--.*?-->//g;
while ($content =~ s/<tr><td>(.*?)<\/td><td>(.*?)<\/td><td>(.*?)<\/td><\/tr>//i) {
my ($subject, $linker) = ($1, $3);
+ my $re_attr_val = '(?:"[^"]+"|\'[^\']+\'|[^\s<>]+)\s*';
+ my $style = {};
+ $subject =~ s/^.*?・<\/font>(?: | )//;
+ while ($subject =~ s/^\s*<([^<>]*)>\s*//) {
+ my $tag = lc($1);
+ my ($tag_part, $attr_part) = split(/\s+/, $tag, 2);
+ $style->{'font-weight'} = 'bold' if ($tag_part eq 'b');
+ while ($attr_part =~ s/([^\s<>=]+)(?:=($re_attr_val))?//) {
+ my ($attr, $val) = ($1, $2);
+ $val =~ s/^"(.*)"$/$1/ or $val =~ s/^'(.*)'$/$1/;
+ $val = $self->unescape($val);
+ if ($attr eq 'style') { $style->{$1} = $2 while ($val =~ s/([^\s:]+)\s*:\s*([^\s:]+)//); }
+ elsif ($attr eq 'color') { $style->{'color'} = $val; }
+ }
+ }
$subject =~ s/\s*<.*?>\s*//g;
- $subject =~ s/^・//;
my ($link, $description) = ($1, $2) if ($linker =~ /<a href=(.*?) .*?>(.*?)<\/a>/i);
my $item = {
'subject' => $self->rewrite($subject),
+ 'style' => $style,
'link' => $self->absolute_url($link, $base),
'description' => $self->rewrite($description)
};
@@ -253,95 +269,205 @@
return @items;
}
-sub parse_calendar {
+sub parse_home_new_album {
my $self = shift;
my $res = (@_) ? shift : $self->response();
return unless ($res and $res->is_success);
my $base = $res->base->as_string;
my $content = $res->content;
- my %icons = ('i_sc-.gif' => '予定', 'i_bd.gif' => '誕生日', 'i_iv1.gif' => '参加イベント', 'i_iv2.gif' => 'イベント');
- my %whethers = ('1' => '晴', '2' => '曇', '3' => '雨', '4' => '雪', '8' => 'のち', '9' => 'ときどき');
my @items = ();
- my $term = $self->parse_calendar_term($res) or return undef;
- if ($content =~ /<table width="670" border="0" cellspacing="1" cellpadding="3">(.+?)<\/table>/s) {
+ if ($content =~ /マイミクシィ最新アルバム(.*?)<table BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=300>/s) {
$content = $1;
- $content =~ s/<tr ALIGN=center BGCOLOR=#FFF1C4>.*?<\/tr>//is;
- while ($content =~ s/<td HEIGHT=65 [^<>]*><font COLOR=#996600>(\S*?)<\/font>(.*?)<\/td>//is) {
- my $date = $1;
- my $text = $2;
- next unless ($date =~ /(\d+)/);
- $date = sprintf('%04d/%02d/%02d', $term->{'year'}, $term->{'month'}, $1);
- if ($text =~ s/<img SRC=(.*?) WIDTH=23 HEIGHT=16 ALIGN=absmiddle>(.*?)<\/font><\/font>//) {
- my $item = { 'subject' => "天気", 'link' => undef, 'name' => $2, 'time' => $date, 'icon' => $1};
- $item->{'icon'} = $self->absolute_url($item->{'icon'}, $base);
- my $weather = ($item->{'icon'} =~ /i_w(\d+).gif$/) ? $1 : '不明';
- $weather =~ s/(\d)/$whethers{$1}/g;
- $item->{'name'} = sprintf("%s(%s\%)", $weather, $self->rewrite($item->{'name'}));
- push(@items, $item);
- }
- my @events = split(/<br>/, $text);
- foreach my $event (@events) {
- my $item = {};
- if ($event =~ /<img SRC=(.*?) WIDTH=16 HEIGHT=16 ALIGN=middle><a HREF=(.*?)>(.*?)<\/a>/) {
- $item = { 'subject' => $1, 'link' => $2, 'name' => $3, 'time' => $date, 'icon' => $1};
- } elsif ($event =~ /<a href=".*?" onClick="MM_openBrWindow\('(view_schedule.pl\?id=\d+)'.*?\)"><img src=(.*?) .*?>(.*?)<\/a>/) {
- $item = { 'subject' => $2, 'link' => $1, 'name' => $3, 'time' => $date, 'icon' => $2};
- } else {
- next;
- }
- $item->{'subject'} = ($item->{'subject'} =~ /([^\/]+)$/ and $icons{$1}) ? $icons{$1} : "不明($1)";
- $item->{'link'} = $self->absolute_url($item->{'link'}, $base);
- $item->{'icon'} = $self->absolute_url($item->{'icon'}, $base);
- $item->{'subject'} = $self->rewrite($item->{'subject'});
- $item->{'name'} = $self->rewrite($item->{'name'});
- push(@items, $item);
- }
+ while ($content =~ s/<img src=.*?>(\d{2})月(\d{2})日.*?<a href=(.+?)>(.*?)<\/a>.*?\((.+?)\)<br CLEAR=all>//is) {
+ my ($date, $link, $subj, $name) = ((sprintf('%02d/%02d', $1, $2)), $3, $4, $5);
+ $subj = $self->rewrite($subj);
+ $name = $self->rewrite($name);
+ $link = $self->absolute_url($link, $base);
+ push(@items, {'time' => $date, 'link' => $link, 'subject' => $subj, 'name' => $name});
+ }
+ }
+ return @items;
+}
+
+sub parse_home_new_bbs {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my @items = ();
+ if ($content =~ /コミュニティ最新書き込み(.*?)<table BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=300>/s) {
+ $content = $1;
+ while ($content =~ s/<img src=.*?>(\d{2})月(\d{2})日.*?<a href=(.+?)>(.*?)<\/a>.*?\((.+?)\)<br CLEAR=all>//is) {
+ my ($date, $link, $subj, $name) = ((sprintf('%02d/%02d', $1, $2)), $3, $4, $5);
+ $subj = $self->rewrite($subj);
+ $name = $self->rewrite($name);
+ $link = $self->absolute_url($link, $base);
+ push(@items, {'time' => $date, 'link' => $link, 'subject' => $subj, 'name' => $name});
+ }
+ }
+ return @items;
+}
+
+sub parse_home_new_comment {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my @items = ();
+ if ($content =~ /日記コメント記入履歴(.*?)<table BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=300>/s) {
+ $content = $1;
+ while ($content =~ s/<img src=.*?>(\d{2})月(\d{2})日.*?<a href=(.+?)>(.*?)<\/a>.*?\((.+?)\)<br CLEAR=all>//is) {
+ my ($date, $link, $subj, $name) = ((sprintf('%02d/%02d', $1, $2)), $3, $4, $5);
+ $subj = $self->rewrite($subj);
+ $name = $self->rewrite($name);
+ $link = $self->absolute_url($link, $base);
+ push(@items, {'time' => $date, 'link' => $link, 'subject' => $subj, 'name' => $name});
+ }
+ }
+ return @items;
+}
+
+sub parse_home_new_friend_diary {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my @items = ();
+ if ($content =~ /<td BGCOLOR=#F2DDB7 WIDTH=80 NOWRAP><font COLOR=#996600>マイミクシィ最新日記<\/font>.*?<\/td>(.*?)<table BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=300>/s) {
+ $content = $1;
+ while ($content =~ s/<img src=.*?>(\d{2})月(\d{2})日.*?<a href=(.+?)>(.*?)<\/a>.*?\((.+?)\)<br CLEAR=all>//is) {
+ my ($date, $link, $subj, $name) = ((sprintf('%02d/%02d', $1, $2)), $3, $4, $5);
+ $subj = $self->rewrite($subj);
+ $name = $self->rewrite($name);
+ $link = $self->absolute_url($link, $base);
+ push(@items, {'time' => $date, 'link' => $link, 'subject' => $subj, 'name' => $name});
+ }
+ }
+ return @items;
+}
+
+sub parse_home_new_review {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my @items = ();
+ if ($content =~ /マイミクシィ最新レビュー(.*?)<table BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=300>/s) {
+ $content = $1;
+ while ($content =~ s/<img src=.*?>(\d{2})月(\d{2})日.*?<a href=(.+?)>(.*?)<\/a>.*?\((.+?)\)<br CLEAR=all>//is) {
+ my ($date, $link, $subj, $name) = ((sprintf('%02d/%02d', $1, $2)), $3, $4, $5);
+ $subj = $self->rewrite($subj);
+ $name = $self->rewrite($name);
+ $link = $self->absolute_url($link, $base);
+ push(@items, {'time' => $date, 'link' => $link, 'subject' => $subj, 'name' => $name});
}
}
return @items;
}
-sub parse_calendar_term {
+sub parse_ajax_new_diary {
my $self = shift;
my $res = (@_) ? shift : $self->response();
return unless ($res and $res->is_success);
my $base = $res->base->as_string;
my $content = $res->content;
- return unless ($content =~ /<a href="calendar.pl\?year=(\d+)&month=(\d+)&pref_id=13">[^&]*?<\/a>/);
- return {'year' => $1, 'month' => $2};
+ my @items = ();
+ my $re_date = '(\d{1,2})月(\d{1,2})日';
+ my $re_link = '<a [^<>]*href="?([^<> ]*?)"?(?: [^<>]*)?>(.*?)<\/a>';
+ my $re_name = '\((.*?)\)';
+ my @today = reverse((localtime)[3..5]);
+ $today[0] += 1900;
+ $today[1] += 1;
+ foreach my $row ($content =~ /<div align=left>(.*?)<\/div>/isg) {
+ next unless ($row =~ /$re_date … $re_link/);
+ my $item = {};
+ my @date = (undef, $1, $2);
+ $item->{'link'} = $self->absolute_url($3, $base);
+ $item->{'subject'} = (defined($4) and length($4)) ? $self->rewrite($4) : '(削除)';
+ $date[0] = ($date[1] > $today[1]) ? $today[0] - 1 : $today[0] if (not defined($date[0]));
+ $item->{'time'} = sprintf('%04d/%02d/%02d', @date);
+ map { $item->{$_} =~ s/^\s+|\s+$//gs } (keys(%{$item}));
+ push(@items, $item);
+ }
+ return @items;
+}
+
+sub parse_community_id {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my $item;
+ if ($content =~ /view_community.pl\?id=(\d+) /) {
+ $item = $1;
+ }
+ return $item;
+}
+
+sub parse_list_bbs {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my @items = ();
+ my $re_date = '<td ALIGN=center ROWSPAN=3 NOWRAP bgcolor=#FFD8B0>(\d{2})月(\d{2})日<br>(\d{1,2}):(\d{2})</td>';
+ my $re_subj = '<td bgcolor=#FFF4E0> (.+?)</td>';
+ my $re_desc = '<td CLASS=h120>(.*?)\n</td>';
+ my $re_name = '\((.*?)\)';
+ my $re_link = '<a href="?(.+?)"?>書き込み\((\d+)\)<\/a>';
+ if ($content =~ /<table BORDER=0 cellspacing=1 cellpadding=3 width=630>(.+)<\/table>/s) {
+ $content = $1 ;
+ while ($content =~ s/<tr VALIGN=top>.*?${re_date}.*?${re_subj}(.*?)${re_desc}.*?${re_link}.*?<\/tr>//is) {
+ my $time = sprintf('%02d/%02d %02d:%02d', $1, $2, $3, $4);
+ my ($subj, $thumbs, $desc, $link, $count) = ($5, $6, $7, $8, $9);
+ $subj = $self->rewrite($subj);
+ $desc = $self->rewrite($desc);
+ $desc =~ s/^$//g;
+ $link = $self->absolute_url($link, $base);
+ my @images = ();
+ while ($thumbs =~ s/MM_openBrWindow\('(.*?)',.+?<img src=["']?([^<>]*?)['"]? border//is){
+ my $img = $self->absolute_url($1, $base);
+ my $thumbimg = $self->absolute_url($2, $base);
+ push(@images, {'thumb_link' => $thumbimg, 'link' => $img});
+ }
+ push(@items, {'time' => $time, 'description' => $desc, 'subject' => $subj, 'link' => $link, 'count' => $count, 'images' => [@images]});
+ }
+ }
+ return @items;
}
-sub parse_calendar_next {
+sub parse_list_bbs_next {
my $self = shift;
my $res = (@_) ? shift : $self->response();
return unless ($res and $res->is_success);
my $base = $res->base->as_string;
my $content = $res->content;
- return unless ($content =~ /<a href="(calendar.pl\?.*?)">([^<>]+?) >>/);
+ return unless ($content =~ /<td ALIGN=right BGCOLOR=#EED6B5>.*?<a href=([^<>]*?list_bbs.pl[^<>]*?)>([^<>]*?)<\/a><\/td>/);
my $subject = $2;
my $link = $self->absolute_url($1, $base);
- my $next = {'link' => $link, 'subject' => $subject};
+ my $next = {'link' => $link, 'subject' => $2};
return $next;
}
-sub parse_calendar_previous {
+sub parse_list_bbs_previous {
my $self = shift;
my $res = (@_) ? shift : $self->response();
return unless ($res and $res->is_success);
my $base = $res->base->as_string;
my $content = $res->content;
- return unless ($content =~ /<a href="(calendar.pl\?.*?)"><< ([^<>]+)/);
+ return unless ($content =~ /<td ALIGN=right BGCOLOR=#EED6B5><a href=([^<>]*?list_bbs.pl[^<>]*?)>([^<>]*?)<\/a>/);
my $subject = $2;
my $link = $self->absolute_url($1, $base);
- my $next = {'link' => $link, 'subject' => $subject};
+ my $next = {'link' => $link, 'subject' => $2};
return $next;
}
-sub parse_diary {
- my $self = shift;
- return $self->parse_view_diary(@_);
-}
-
sub parse_list_bookmark {
my $self = shift;
my $res = (@_) ? shift : $self->response();
@@ -349,7 +475,7 @@
my $base = $res->base->as_string;
my $content = $res->content;
my @items = ();
- if ($content =~ /<table BORDER=0 CELLSPACING=1 CELLPADDING=4 WIDTH=630>(.+?)<!--フッタ-->/s) {
+ if ($content =~ /<table BORDER=0 CELLSPACING=1 CELLPADDING=4 WIDTH=630>(.+?)<img src=["']?http:\/\/\S*?\/q_brown3.gif['"]? [^<>]*?>/s) {
$content = $1;
while ($content =~ s/<table BORDER=0 CELLSPACING=1 CELLPADDING=4 WIDTH=550>(.*?)<\/table>//is) {
my $record = $1;
@@ -516,9 +642,10 @@
my $base = $res->base->as_string;
my $content = $res->content;
my @items = ();
- if ($content =~ /<!-- start: monthly menu -->(.+)<!-- end: monthly menu -->/s) {
+ if ($content =~ /<img src=.*? ALT=各月の日記 .*?>(.+?)<\/table>/is) {
$content = $1;
- while ($content =~ s/<a HREF=['"]?(list_diary.pl\?year=(\d+)\&month=(\d+))['"]?.*?>.*?<\/a>//is) {
+ $content =~ s/\s+/ /gs;
+ while ($content =~ s/<a HREF=['"]?(list_diary.pl\?year=(\d+)\&month=(\d+))["']?.*?>.*?<\/a>//is) {
push(@items, {'link' => $self->absolute_url($1, $base), 'year' => $2, 'month' => $3});
}
}
@@ -590,6 +717,64 @@
return $previous;
}
+sub parse_list_member {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my @items = ();
+ if ($content =~ /<table BORDER=0 CELLSPACING=1 CELLPADDING=2 WIDTH=560>(.+?)<\/table>/s) {
+ $content = $1 ;
+ while ($content =~ s/<tr ALIGN=center BGCOLOR=#FFFFFF>(.*?)<tr ALIGN=center BGCOLOR=#FFF4E0>(.*?)<\/tr>//is) {
+ my ($image_part, $text_part) = ($1, $2);
+ my @images = ($image_part =~ /<td WIDTH=20% HEIGHT=100 background=http:\/\/img.mixi.jp\/img\/bg_line.gif>.*?<\/td>/gi);
+ my @texts = ($text_part =~ /<td>(.*?)<\/td>/gi);
+ for (my $i = 0; $i < @images or $i < @texts; $i++) {
+ my $item = {};
+ my ($image, $text) = ($images[$i], $texts[$i]);
+ ($item->{'subject'}, $item->{'count'}) = ($1, $2) if ($text =~ /^\s*(.+?)\((\d+)\)/);
+ ($item->{'background'}, $item->{'link'}, $item->{'image'}) = ($1, $2, $3) if ($image =~ /<td .*? background=([^<> ]*).*?><a href=(.*?)><img SRC=(.*?) border=0><\/a>/i);
+ if ($item->{'link'}) {
+ $item->{'subject'} = $self->rewrite($item->{'subject'});
+ $item->{'link'} = $self->absolute_url($item->{'link'}, $base);
+ $item->{'id'} = $2 if ($item->{'link'} =~ /(.*?)?id=(\d*)/);
+ $item->{'image'} = $self->absolute_url($item->{'image'}, $base);
+ $item->{'background'} = $self->absolute_url($item->{'background'}, $base);
+ push(@items, $item);
+ }
+ }
+ }
+ }
+ return @items;
+}
+
+sub parse_list_member_next {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ return unless ($content =~ / <a href=([^<>]*?list_member.pl\?[^<>\s]*page=[^<>\s]*)>((?:(?!<\/a>).)*)<\/a>/);
+ my $subject = $2;
+ my $link = $self->absolute_url($1, $base);
+ my $next = {'link' => $link, 'subject' => $2};
+ return $next;
+}
+
+sub parse_list_member_previous {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->request->uri->as_string;
+ my $content = $res->content;
+ return unless ($content =~ /<a href=([^<>\s]*list_member.pl\?[^<>\s]*page=[^<>\s]*)>((?:(?!<\/a>).)*)<\/a> /);
+ my $subject = $2;
+ my $link = $self->absolute_url($1, $base);
+ my $previous = {'link' => $link, 'subject' => $2};
+ return $previous;
+}
+
sub parse_list_message {
my $self = shift;
my $res = (@_) ? shift : $self->response();
@@ -656,6 +841,43 @@
return @items;
}
+sub parse_list_request {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my @items = ();
+ if ($content =~ /<table BORDER=0 CELLSPACING=1 CELLPADDING=4 WIDTH=630>(.+?)<table BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=720 BGCOLOR=#FF9933>/s) {
+ $content = $1;
+ while ($content =~ s/<table BORDER=0 CELLSPACING=1 CELLPADDING=4 WIDTH=550>(.*?)<\/table>//is) {
+ my $record = $1;
+ my @lines = ($record =~ /<tr.*?>(.*?)<\/tr>/gis);
+ my $item = {};
+ # parse record
+ ($item->{'link'}, $item->{'image'}) = ($1, $2) if ($lines[0] =~ /<td WIDTH=90 .*?><a href="([^"]*show_friend.pl\?id=\d+)"><img SRC="([^"]*)".*?>/is);
+ ($item->{'subject'}, $item->{'gender'}) = ($1, $2) if ($lines[0] =~ /<td COLSPAN=2 BGCOLOR=#FFFFFF>(.*?) \((.*?)\)<\/td>/is);
+ $item->{'description'} = $1 if ($lines[1] =~ /<td COLSPAN=2 BGCOLOR=#FFFFFF>(.*?)<\/td>/is);
+ $item->{'message'} = $1 if ($lines[2] =~ /<td COLSPAN=2 BGCOLOR=#FFFFFF>(.*?)<\/td>/is);
+ $item->{'time'} = $1 if ($lines[3] =~ /<td BGCOLOR=#FFFFFF WIDTH=140>(.*?)<\/td>/is);
+ while ($lines[3] =~ s/<a href="(.*?)"><img src=["']?(.*?)['"]? ALT=["']?(.*?)['"]? [^<>]*?><\/a>//) {
+ my $button = { 'link' => $1, 'image' => $2, 'title' => $3 };
+ map { $button->{$_} = $self->absolute_url($button->{$_}, $base) } qw(link image);
+ map { $button->{$_} = $self->rewrite($button->{$_}, $base) } qw(title);
+ $item->{'button'} = [] unless ($item->{'button'});
+ push(@{$item->{'button'}}, $button);
+ }
+ # format
+ map { $item->{$_} = $self->absolute_url($item->{$_}, $base) } qw(link image);
+ map { $item->{$_} = $self->rewrite($item->{$_}, $base) } qw(subject description message gender);
+ $item->{'time'} = $self->convert_login_time($item->{'time'}) if ($item->{'time'});
+ push(@items, $item) if ($item->{'subject'} and $item->{'link'});
+ }
+ }
+ @items = sort { $b->{'time'} cmp $a->{'time'} } @items;
+ return @items;
+}
+
sub parse_new_album {
my $self = shift;
return $self->parse_standard_history(@_);
@@ -681,7 +903,62 @@
return $self->parse_standard_history(@_);
}
-sub parse_new_diary {
+sub parse_new_friend_diary {
+ my $self = shift;
+ return $self->parse_standard_history(@_);
+}
+
+sub parse_new_friend_diary_next {
+ my $self = shift;
+ return $self->parse_standard_history_next(@_);
+}
+
+sub parse_new_friend_diary_previous {
+ my $self = shift;
+ return $self->parse_standard_history_previous(@_);
+}
+
+sub parse_new_review {
+ my $self = shift;
+ return $self->parse_standard_history(@_);
+}
+
+sub parse_release_info {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my @items = ();
+ my $re_subj = '<b><font COLOR=#605048>(.+?)</font></b>';
+ my $re_date = '<td ALIGN=right><font COLOR=#605048>(\d{4}).(\d{2}).(\d{2})</font></td>';
+ my $re_desc = '<td CLASS=h130>(.*?)</td>';
+ if ($content =~ /新機能リリース・障害のご報告(.*?)<!--フッタ-->/s) {
+ $content = $1;
+ while ($content =~ s/<table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH=520 BGCOLOR=#F7F0E6>.*?${re_subj}.*?${re_date}.*?${re_desc}.*?<!--▼1つ分ここまで-->//is) {
+ my $subj = $1;
+ my $date = sprintf('%04d/%02d/%02d', $2, $3, $4);
+ my $desc = $5;
+ $subj = $self->rewrite($subj);
+ $desc = $self->rewrite($desc);
+ $desc =~ s/^$//g;
+ push(@items, {'time' => $date, 'description' => $desc, 'subject' => $subj});
+ }
+ }
+ return @items;
+}
+
+sub parse_self_id {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my $self_id = ($content =~ /\(URL は http:\/\/mixi.jp\/show_friend.pl\?id=(\d+) です。\)/) ? $1 : 0;
+ return $self_id;
+}
+
+sub parse_search_diary {
my $self = shift;
my $res = (@_) ? shift : $self->response();
return unless ($res and $res->is_success);
@@ -690,7 +967,7 @@
my @items = ();
my @time = localtime();
my ($month, $year) = ($time[4] + 1, $time[5] + 1900);
- if ($content =~ /<!--\/\/\/\/\/ 最新日記検索ここまで \/\/\/\/\/-->(.+?)<!--フッタ-->/s) {
+ if ($content =~ m{<!--///// 最新日記検索ここまで /////-->(.+?)<!--フッタ-->}s) {
$content = $1;
while ($content =~ s/<table BORDER=0 CELLSPACING=1 CELLPADDING=4 WIDTH=550>(.*?)<\/table>//is) {
my $record = $1;
@@ -717,80 +994,114 @@
return @items;
}
-sub parse_new_diary_next {
+sub parse_search_diary_next {
my $self = shift;
my $res = (@_) ? shift : $self->response();
return unless ($res and $res->is_success);
my $base = $res->base->as_string;
my $content = $res->content;
- return unless ($content =~ /<td ALIGN=right BGCOLOR=#EED6B5>.*?<a href=([^<>]*?new_diary.pl[^<>]*?)>([^<>]*?)<\/a><\/td>/);
+ return unless ($content =~ /<td ALIGN=right BGCOLOR=#EED6B5>.*?<a href=([^<>]*?search_diary.pl[^<>]*?)>([^<>]*?)<\/a><\/td>/);
my $subject = $2;
my $link = $self->absolute_url($1, $base);
my $next = {'link' => $link, 'subject' => $2};
return $next;
}
-sub parse_new_diary_previous {
+sub parse_search_diary_previous {
my $self = shift;
my $res = (@_) ? shift : $self->response();
return unless ($res and $res->is_success);
my $base = $res->base->as_string;
my $content = $res->content;
- return unless ($content =~ /<td ALIGN=right BGCOLOR=#EED6B5><a href=([^<>]*?new_diary.pl[^<>]*?)>([^<>]*?)<\/a>/);
+ return unless ($content =~ /<td ALIGN=right BGCOLOR=#EED6B5><a href=([^<>]*?search_diary.pl[^<>]*?)>([^<>]*?)<\/a>/);
my $subject = $2;
my $link = $self->absolute_url($1, $base);
my $next = {'link' => $link, 'subject' => $2};
return $next;
}
-sub parse_new_friend_diary {
- my $self = shift;
- return $self->parse_standard_history(@_);
-}
-
-sub parse_new_friend_diary_next {
- my $self = shift;
- return $self->parse_standard_history_next(@_);
-# my $self = shift;
-# my $res = (@_) ? shift : $self->response();
-# return unless ($res and $res->is_success);
-# my $base = $res->base->as_string;
-# my $content = $res->content;
-# # return unless ($content =~ /<td ALIGN=right BGCOLOR=#EED6B5>[^\r\n]*?<a href=["']?(.+?)['"]?>([^<>]+)<\/a><\/td><\/tr>/);
-# return unless ($content =~ /<td ALIGN=right BGCOLOR=#EED6B5>[^\r\n]*?<a href=["']?([^>]+?)['"]?>([^<>]+)<\/a><\/td><\/tr>/);
-# my $subject = $2;
-# my $link = $self->absolute_url($1, $base);
-# my $next = {'link' => $link, 'subject' => $2};
-# return $next;
+sub parse_show_calendar {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my %icons = ('i_sc-.gif' => '予定', 'i_bd.gif' => '誕生日', 'i_iv1.gif' => '参加イベント', 'i_iv2.gif' => 'イベント');
+ my %whethers = ('1' => '晴', '2' => '曇', '3' => '雨', '4' => '雪', '8' => 'のち', '9' => 'ときどき');
+ my @items = ();
+ my $term = $self->parse_show_calendar_term($res) or return undef;
+ if ($content =~ /<table width="670" border="0" cellspacing="1" cellpadding="3">(.+?)<\/table>/s) {
+ $content = $1;
+ $content =~ s/<tr ALIGN=center BGCOLOR=#FFF1C4>.*?<\/tr>//is;
+ while ($content =~ s/<td HEIGHT=65 [^<>]*><font COLOR=#996600>(\S*?)<\/font>(.*?)<\/td>//is) {
+ my $date = $1;
+ my $text = $2;
+ next unless ($date =~ /(\d+)/);
+ $date = sprintf('%04d/%02d/%02d', $term->{'year'}, $term->{'month'}, $1);
+ if ($text =~ s/<img SRC=(.*?) WIDTH=23 HEIGHT=16 ALIGN=absmiddle>(.*?)<\/font><\/font>//) {
+ my $item = { 'subject' => "天気", 'link' => undef, 'name' => $2, 'time' => $date, 'icon' => $1};
+ $item->{'icon'} = $self->absolute_url($item->{'icon'}, $base);
+ my $weather = ($item->{'icon'} =~ /i_w(\d+).gif$/) ? $1 : '不明';
+ $weather =~ s/(\d)/$whethers{$1}/g;
+ $item->{'name'} = sprintf("%s(%s%%)", $weather, $self->rewrite($item->{'name'}));
+ push(@items, $item);
+ }
+ my @events = split(/<br>/, $text);
+ foreach my $event (@events) {
+ my $item = {};
+ if ($event =~ /<img SRC=(.*?) WIDTH=16 HEIGHT=16 ALIGN=middle><a HREF=(.*?)>(.*?)<\/a>/) {
+ $item = { 'subject' => $1, 'link' => $2, 'name' => $3, 'time' => $date, 'icon' => $1};
+ } elsif ($event =~ /<a href=".*?" onClick="MM_openBrWindow\('(view_schedule.pl\?id=\d+)'.*?\)"><img src=(.*?) .*?>(.*?)<\/a>/) {
+ $item = { 'subject' => $2, 'link' => $1, 'name' => $3, 'time' => $date, 'icon' => $2};
+ } else {
+ next;
+ }
+ $item->{'subject'} = ($item->{'subject'} =~ /([^\/]+)$/ and $icons{$1}) ? $icons{$1} : "不明($1)";
+ $item->{'link'} = $self->absolute_url($item->{'link'}, $base);
+ $item->{'icon'} = $self->absolute_url($item->{'icon'}, $base);
+ $item->{'subject'} = $self->rewrite($item->{'subject'});
+ $item->{'name'} = $self->rewrite($item->{'name'});
+ push(@items, $item);
+ }
+ }
+ }
+ return @items;
}
-sub parse_new_friend_diary_previous {
+sub parse_show_calendar_term {
my $self = shift;
- return $self->parse_standard_history_previous(@_);
-# my $res = (@_) ? shift : $self->response();
-# return unless ($res and $res->is_success);
-# my $base = $res->request->uri->as_string;
-# my $content = $res->content;
-# return unless ($content =~ /<td ALIGN=right BGCOLOR=#EED6B5><a href=["']?(.+?)['"]?>([^<>]+)<\/a>[^\r\n]*?<\/td><\/tr>/);
-# my $subject = $2;
-# my $link = $self->absolute_url($1, $base);
-# my $previous = {'link' => $link, 'subject' => $2};
-# return $previous;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ return unless ($content =~ /<a href="show_calendar.pl\?year=(\d+)&month=(\d+)&pref_id=13">[^&]*?<\/a>/);
+ return {'year' => $1, 'month' => $2};
}
-sub parse_new_review {
+sub parse_show_calendar_next {
my $self = shift;
- return $self->parse_standard_history(@_);
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ return unless ($content =~ /<a href="(show_calendar.pl\?.*?)">([^<>]+?) >>/);
+ my $subject = $2;
+ my $link = $self->absolute_url($1, $base);
+ my $next = {'link' => $link, 'subject' => $subject};
+ return $next;
}
-sub parse_self_id {
+sub parse_show_calendar_previous {
my $self = shift;
my $res = (@_) ? shift : $self->response();
return unless ($res and $res->is_success);
my $base = $res->base->as_string;
my $content = $res->content;
- my $self_id = ($content =~ /\(URL は http:\/\/mixi.jp\/show_friend.pl\?id=(\d+) です。\)/) ? $1 : 0;
- return $self_id;
+ return unless ($content =~ /<a href="(show_calendar.pl\?.*?)"><< ([^<>]+)/);
+ my $subject = $2;
+ my $link = $self->absolute_url($1, $base);
+ my $next = {'link' => $link, 'subject' => $subject};
+ return $next;
}
sub parse_show_friend_outline {
@@ -858,6 +1169,33 @@
return;
}
+sub parse_show_intro {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my @items = ();
+ if ($content =~ /からの紹介文(.+?)<!--フッタ-->/s) {
+ $content = $1;
+ while ($content =~ s/<tr bgcolor=#FFFFFF>.*?<a href="(.+?)"><img src="(.+?)".*?\n(.+?)<\/td>.*?<td WIDTH=480>\n(.*?)\n(.*?)<\/td>//is) {
+ my ($link, $img, $name, $rel, $desc) = ($1, $2, $3, $4, $5);
+ $rel =~ s/関係:(.+?)<br>/$1/;
+ my $intro = ($desc =~ /edit_intro.pl\?id=.+?\&type=edit/) ? "1" : "0";
+ my $delete = ($desc =~ s/<a href="delete_intro.pl\?id=(\d+)">削除<\/a>//s) ? "1" : "0";
+ $name = $self->rewrite($name);
+ $rel = $self->rewrite($rel);
+ $desc = $self->rewrite($desc);
+ $desc =~ s/この友人を紹介する//;
+ $desc =~ s/[\r\n]+//ig;
+ $link = $self->absolute_url($link, $base);
+ my $item = {'link' => $link, 'name' => $name, 'image' => $img, 'relation' => $rel, 'description' => $desc, 'introduction' => $intro, 'detele' => $delete};
+ push(@items, $item);
+ }
+ }
+ return @items;
+}
+
sub parse_show_log {
my $self = shift;
my $res = (@_) ? shift : $self->response();
@@ -879,16 +1217,108 @@
return @items;
}
-sub parse_show_log_count {
- my $self = shift;
- my $res = (@_) ? shift : $self->response();
- return unless ($res and $res->is_success);
- my $base = $res->base->as_string;
- my $content = $res->content;
- my $count = ($content =~ /ページ全体のアクセス数:<b>(\d+)<\/b> アクセス/) ? $1 : 0;
- return $count;
-}
-
+sub parse_show_log_count {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my $count = ($content =~ /ページ全体のアクセス数:<b>(\d+)<\/b> アクセス/) ? $1 : 0;
+ return $count;
+}
+
+sub parse_view_album {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my @items = ();
+ if ($content =~ /概要ここから(.+?)<!--フッタ-->/s) {
+ my $img = $1 if ($content =~ /width=250><img ALT="" SRC="(.*?)" VSPACE=4><\/td>/);
+ my $name = $1 if ($content =~ /<b>(.*?)さんのフォトアルバム/);
+ my $subj = $1 if ($content =~ /タイトル.*?<b>(.*?)<\/b>/s);
+ my $desc = $1 if ($content =~ /説明.*?CLASS=h120>(.*?)<\/td>/s);
+ my $level = $1 if ($content =~ /公開レベル.*?<td bgcolor=#FFFFFF>(.*?)<br>/s);
+ my $time = sprintf('%04d/%02d/%02d %02d:%02d', $1, $2, $3, $5, $5) if ($content =~ /作成日時.*?<td bgcolor=#FFFFFF>(\d{4})年(\d{2})月(\d{2})日 (\d{2}):(\d{2})<\/td>/s);
+ my $comm = $1 if ($content =~ />コメント\((\d+)\)/);
+ my $number = $1 if ($content =~ /写真一覧.*?\ (\d+)枚/);
+ $name = $self->rewrite($name);
+ $subj = $self->rewrite($subj);
+ $desc = $self->rewrite($desc);
+ my $item = { 'image' => $self->absolute_url($img, $base), 'name' => $name, 'subject' => $subj, 'description' => $desc, 'level' => $level, 'time' => $time, 'comment_number' => $comm, 'photo_number' => $number};
+ push(@items, $item);
+ }
+ return @items;
+}
+
+sub parse_view_album_comment {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my @items = ();
+ if ($content =~ /写真一覧ここまで(.*?)<!--フッタ-->/s) {
+ $content = $1;
+ while ($content =~ s/<td rowspan="2" width="110" bgcolor="#f2ddb7" align="center" valign="top" nowrap>\n(\d{4})年(\d{2})月(\d{2})日<br>(\d{2}):(\d{2})\n<\/td>.*?<a href="(.+?)">(.+?)<\/a>.*?<td class="h120">(.*?)<\/td>//s) {
+ my ($time, $link, $name, $desc) = ((sprintf('%04d/%02d/%02d %02d:%02d', $1, $2, $3, $4, $5)), $6, $7, $8);
+ my $item = { 'time' => $time, 'link' => $self->absolute_url($link, $base), 'name' => $self->rewrite($name), 'description' => $self->rewrite($desc)};
+ push(@items, $item);
+ }
+ }
+ return @items;
+}
+
+sub parse_view_album_photo {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my @items = ();
+ if ($content =~ /写真一覧ここから(.*?)写真一覧ここまで/s) {
+ $content = $1;
+ while ($content =~ s/<td.*?<img alt="(.+?)" src="(.+?)".*?<a href="(.+?)">(.+?)<\/a><\/td>//) {
+ my ($alt, $thumb, $link, $subj) = ($1, $2, $3, $4);
+ my $item = { 'description' => $alt, 'thumb_link' => $self->absolute_url($thumb, $base), 'link' => $self->absolute_url($link, $base), 'subject' => $self->rewrite($subj)};
+ push(@items, $item);
+ }
+ }
+ return @items;
+}
+
+sub parse_view_bbs {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my @items = ();
+ my $re_date = '<td rowspan="3" width="110" bgcolor="#ffd8b0" align="center" valign="top" nowrap>(\d{4})年(\d{2})月(\d{2})日<br>(\d{1,2}):(\d{2})</td>';
+ my $re_subj = '<td bgcolor="#fff4e0"> (.+?)</td>';
+ my $re_desc = '</table>(.+?)</td>';
+ my $re_c_date = '<td rowspan="2" width="110" bgcolor="#f2ddb7" align="center" nowrap>\n(\d{4})年(\d{2})月(\d{2})日<br>\n(\d{1,2}):(\d{2})';
+ my $re_c_desc = '<td class="h120">(.+?)\n</td>';
+ my $re_link = '<a href="?(.+?)"?>(.*?)<\/a>';
+ if ($content =~ s/<!-- TOPIC: start -->.*?${re_date}.*?${re_subj}.*?${re_link}(.*?)${re_desc}(.*?)$//is) {
+ my ($time, $subj, $link, $name, $imgs, $desc, $comm) = (sprintf('%04d/%02d/%02d %02d:%02d', $1,$2,$3,$4,$5), $6, $7, $8, $9, $10, $11);
+ ($desc, $subj) = map { s/[\r\n]+//g; s/<br>/\n/g; $_ = $self->rewrite($_); } ($desc, $subj);
+ my $item = { 'time' => $time, 'description' => $desc, 'subject' => $subj, 'link' => $res->request->uri->as_string, 'images' => [], 'comments' => [] , 'name' => $name, 'name_link' => $self->absolute_url($link, $base)};
+ foreach my $image ($imgs =~ /<td width=130[^<>]*>(.*?)<\/td>/g) {
+ next unless ($image =~ /<a [^<>]*'show_picture.pl\?img_src=(.*?)'[^<>]*><img src=([^ ]*) border=0>/);
+ push(@{$item->{'images'}}, {'link' => $self->absolute_url($1, $base), 'thumb_link' => $self->absolute_url($2, $base)});
+ }
+ while ($comm =~ s/.*?${re_c_date}.*?${re_link}.*?${re_c_desc}.*?<\/table>//is){
+ my ($time, $link, $name, $desc) = (sprintf('%04d/%02d/%02d %02d:%02d', $1,$2,$3,$4,$5), $6, $7, $8);
+ ($name, $desc) = map { s/[\r\n]+//g; s/<br>/\n/g; $_ = $self->rewrite($_); } ($name, $desc);
+ push(@{$item->{'comments'}}, {'time' => $time, 'link' => $self->absolute_url($link, $base), 'name' => $name, 'description' => $desc});
+ }
+ push(@items, $item);
+ }
+ return @items;
+}
+
sub parse_view_diary {
my $self = shift;
my $res = (@_) ? shift : $self->response();
@@ -899,13 +1329,13 @@
my $re_date = '<td ALIGN=center ROWSPAN=2 NOWRAP WIDTH=95 bgcolor=#FFD8B0>(\d{4})年(\d{2})月(\d{2})日<br>(\d{1,2}):(\d{2})</td>';
my $re_subj = '<td BGCOLOR=#FFF4E0 WIDTH=430> (.+?)</td>';
my $re_desc = '<td CLASS=h12>(.+?)</td>';
-# my $re_c_date = '<td rowspan="2" align="center" width="95" bgcolor="#f2ddb7" nowrap>\n(\d{4})年(\d{2})月(\d{2})日<br>(\d{1,2}):(\d{2})<br>';
my $re_c_date = '<td rowspan="2" align="center" width="95" bgcolor="#f2ddb7" nowrap>\n(\d{4})年(\d{2})月(\d{2})日<br>(\d{1,2}):(\d{2})';
my $re_link = '<a href="?(.+?)"?>(.+?)<\/a>';
if ($content =~ s/<tr VALIGN=top>.*?${re_date}.*?${re_subj}(.*?)${re_desc}(.+)//is) {
my ($time, $subj, $imgs, $desc, $comm) = (sprintf('%04d/%02d/%02d %02d:%02d', $1,$2,$3,$4,$5), $6, $7, $8, $9);
+ my $level = { 'description' => $self->rewrite($2), 'link' => $self->absolute_url($1, $base) } if ($content =~ /<img src="([^"]+)" alt="([^"]+)" height="\d+" hspace="\d+" width="\d+">/);
($desc, $subj) = map { s/[\r\n]+//g; s/<br>/\n/g; $_ = $self->rewrite($_); } ($desc, $subj);
- my $item = { 'time' => $time, 'description' => $desc, 'subject' => $subj, 'link' => $res->request->uri->as_string, 'images' => [], 'comments' => [] };
+ my $item = { 'time' => $time, 'description' => $desc, 'subject' => $subj, 'link' => $res->request->uri->as_string, 'images' => [], 'comments' => [], 'level' => $level };
foreach my $image ($imgs =~ /<td width=130[^<>]*>(.*?)<\/td>/g) {
next unless ($image =~ /<a [^<>]*'show_picture.pl\?img_src=(.*?)'[^<>]*><img src=([^ ]*) border=0>/);
push(@{$item->{'images'}}, {'link' => $self->absolute_url($1, $base), 'thumb_link' => $self->absolute_url($2, $base)});
@@ -920,6 +1350,45 @@
return @items;
}
+sub parse_view_event {
+ my $self = shift;
+ my $res = (@_) ? shift : $self->response();
+ return unless ($res and $res->is_success);
+ my $base = $res->base->as_string;
+ my $content = $res->content;
+ my @items = ();
+ my $re_date = '<td ROWSPAN=11 BGCOLOR=#FFD8B0 ALIGN=center VALIGN=top WIDTH=110>(\d{4})年(\d{2})月(\d{2})日<br>(\d{1,2}):(\d{2})</td>';
+ my $re_subj = '<td BGCOLOR=#FFF4E0> (.+?)</td>';
+ my $re_link = '<a href="?(.+?)"?>(.*?)<\/a>';
+ my $re_hold = '<td BGCOLOR=#FFFFFF>\n (.*?)\n</td>';
+ my $re_dead = '<td BGCOLOR=#FFFFFF> (.*?)</td>';
+ my $re_desc = '<table BORDER=0 CELLSPACING=0 CELLPADDING=5>(.*?)</tr>';
+ my $re_c_date = '<td ROWSPAN=.*?\n(\d{4})年(\d{2})月(\d{2})日<br>\n(\d{1,2}):(\d{2})<br>\n';
+ my $re_c_desc = '<td CLASS="?h120"?>(.*?)\n</tr>';
+ if ($content =~ s/<table BORDER=0 CELLSPACING=0 CELLPADDING=1 BGCOLOR=#DFA473>.*?${re_date}(.*?)${re_subj}.*?${re_link}.*?${re_hold}.*?${re_hold}.*?${re_desc}.*?${re_dead}(.*?)<!-- TOPIC: end -->(.*?)<!--フッタ-->//is) {
+ my ($time, $imgs, $subj, $link, $name, $date, $location, $desc, $deadline, $join, $comm) = (sprintf('%04d/%02d/%02d %02d:%02d', $1,$2,$3,$4,$5), $6, $7, $8, $9, $10, $11, $12, $13, $14, $15);
+ if ($join =~ /VALUE=" イベントに参加する "/i) { $join = 1;
+ } elsif ($join =~ /VALUE=" 参加をキャンセルする "/i) { $join = 2;
+ } else { $join = 0;
+ }
+ ($desc, $subj) = map { s/[\r\n]+//g; s/<br>/\n/g; $_ = $self->rewrite($_); } ($desc, $subj);
+ my $item = { 'time' => $time, 'description' => $desc, 'subject' => $subj, 'link' => $res->request->uri->as_string, 'images' => [], 'comments' => [] , 'name' => $name, 'name_link' => $self->absolute_url($link, $base), 'date' => $date, 'location' => $location, 'deadline' => $deadline, 'join' => $join};
+ foreach my $image ($imgs =~ /<td width=130[^<>]*>(.*?)<\/td>/g) {
+ next unless ($image =~ /<a [^<>]*'show_picture.pl\?img_src=(.*?)'[^<>]*><img src=([^ ]*) border=0>/);
+ push(@{$item->{'images'}}, {'link' => $self->absolute_url($1, $base), 'thumb_link' => $self->absolute_url($2, $base)});
+ }
+ while ($comm =~ s/${re_c_date}.*?${re_link}.*?${re_c_desc}//is) {
+ my ($time, $link, $name, $desc) = (sprintf('%04d/%02d/%02d %02d:%02d', $1,$2,$3,$4,$5), $6, $7, $8);
+ my $imgs;
+ ($imgs, $desc) = ($1, $2) if ($desc =~ /<table>(.+?)<\/table>.*?(.+?)<\/td>/);
+ ($name, $desc) = map { s/[\r\n]+//g; s/<br>/\n/g; $_ = $self->rewrite($_); } ($name, $desc);
+ push(@{$item->{'comments'}}, {'time' => $time, 'link' => $self->absolute_url($link, $base), 'name' => $name, 'description' => $desc});
+ }
+ push(@items, $item);
+ }
+ return @items;
+}
+
sub parse_view_message {
my $self = shift;
my $res = (@_) ? shift : $self->response();
@@ -1108,44 +1577,66 @@
return $self->parse_tool_bar();
}
-sub get_information {
+sub get_information { my $self = shift; return $self->get_standard_data('parse_information', 'home.pl', @_); }
+sub get_home_new_album { my $self = shift; return $self->get_standard_data('parse_home_new_album', 'home.pl', @_); }
+sub get_home_new_bbs { my $self = shift; return $self->get_standard_data('parse_home_new_bbs', 'home.pl', @_); }
+sub get_home_new_comment { my $self = shift; return $self->get_standard_data('parse_home_new_comment', 'home.pl', @_); }
+sub get_home_new_friend_diary { my $self = shift; return $self->get_standard_data('parse_home_new_friend_diary', 'home.pl', @_); }
+sub get_home_new_review { my $self = shift; return $self->get_standard_data('parse_home_new_review', 'home.pl', @_); }
+
+sub get_ajax_new_diary {
my $self = shift;
- my $url = 'home.pl';
- $url = shift if (@_ and $_[0] ne 'refresh');
- $self->set_response($url, @_) or return;
- return $self->parse_information();
+ my $url = 'ajax_new_diary.pll';
+ $url = shift if (@_ and $_[0] ne 'refresh' and $_[0] ne 'friend_id');
+ my $refresh = shift if (@_ and $_[0] eq 'refresh');
+ my %param = @_;
+ if (defined($param{'friend_id'}) and length($param{'friend_id'}) and $url !~ /[\?\&]friend_id=/) {
+ $url .= ($url =~ /\?/) ? "&friend_id=$param{'friend_id'}" : "?friend_id=$param{'friend_id'}";
+ }
+ return $self->get_standard_data('parse_ajax_new_diary', qr/ajax_new_diary\.pl/, $url, $refresh);
}
-sub get_calendar {
+sub get_community_id {
my $self = shift;
- my $url = 'calendar.pl';
- $url = shift if (@_ and $_[0] ne 'refresh');
- $self->set_response($url, @_) or return;
- return $self->parse_calendar();
+ return $self->get_standard_data('parse_community_id', qr/view_community\.pl/, @_);
}
-sub get_calendar_term {
- my $self = shift;
- my $url = 'calendar.pl';
- $url = shift if (@_ and $_[0] ne 'refresh');
- $self->set_response($url, @_) or return;
- return $self->parse_calendar_term();
+sub get_list_bbs {
+ my $self = shift;
+ my $url = 'list_bbs.pl';
+ $url = shift if (@_ and $_[0] ne 'refresh' and $_[0] ne 'id');
+ my $refresh = shift if (@_ and $_[0] eq 'refresh');
+ my %param = @_;
+ if (defined($param{'id'}) and length($param{'id'}) and $url !~ /[\?\&]id=/) {
+ $url .= ($url =~ /\?/) ? "&id=$param{'id'}" : "?id=$param{'id'}";
+ }
+ return $self->get_standard_data('parse_list_bbs', qr/list_bbs\.pl/, $url, $refresh);
}
-sub get_calendar_next {
- my $self = shift;
- my $url = 'calendar.pl';
- $url = shift if (@_ and $_[0] ne 'refresh');
- $self->set_response($url, @_) or return;
- return $self->parse_calendar_next();
+sub get_list_bbs_next {
+ my $self = shift;
+ my $url = 'list_bbs.pl';
+ $url = shift if (@_ and $_[0] ne 'refresh' and $_[0] ne 'id');
+ my $refresh = shift if (@_ and $_[0] eq 'refresh');
+ my %param = @_;
+ if (defined($param{'id'}) and length($param{'id'}) and $url !~ /[\?\&]id=/) {
+ $url .= ($url =~ /\?/) ? "&id=$param{'id'}" : "?id=$param{'id'}";
+ }
+ $self->set_response($url, $refresh) or return;
+ return $self->parse_list_bbs_next();
}
-sub get_calendar_previous {
- my $self = shift;
- my $url = 'calendar.pl';
- $url = shift if (@_ and $_[0] ne 'refresh');
- $self->set_response($url, @_) or return;
- return $self->parse_calendar_previous();
+sub get_list_bbs_previous {
+ my $self = shift;
+ my $url = 'list_bbs.pl';
+ $url = shift if (@_ and $_[0] ne 'refresh' and $_[0] ne 'id');
+ my $refresh = shift if (@_ and $_[0] eq 'refresh');
+ my %param = @_;
+ if (defined($param{'id'}) and length($param{'id'}) and $url !~ /[\?\&]id=/) {
+ $url .= ($url =~ /\?/) ? "&id=$param{'id'}" : "?id=$param{'id'}";
+ }
+ $self->set_response($url, $refresh) or return;
+ return $self->parse_list_bbs_previous();
}
sub get_list_bookmark {
@@ -1252,6 +1743,44 @@
return $self->parse_list_friend_previous();
}
+sub get_list_member {
+ my $self = shift;
+ my $url = 'list_member.pl';
+ $url = shift if (@_ and $_[0] ne 'refresh' and $_[0] ne 'id');
+ my $refresh = shift if (@_ and $_[0] eq 'refresh');
+ my %param = @_;
+ if (defined($param{'id'}) and length($param{'id'}) and $url !~ /[\?\&]id=/) {
+ $url .= ($url =~ /\?/) ? "&id=$param{'id'}" : "?id=$param{'id'}";
+ }
+ return $self->get_standard_data('parse_list_member', qr/list_member\.pl/, $url, $refresh);
+}
+
+sub get_list_member_next {
+ my $self = shift;
+ my $url = 'list_member.pl';
+ $url = shift if (@_ and $_[0] ne 'refresh' and $_[0] ne 'id');
+ my $refresh = shift if (@_ and $_[0] eq 'refresh');
+ my %param = @_;
+ if (defined($param{'id'}) and length($param{'id'}) and $url !~ /[\?\&]id=/) {
+ $url .= ($url =~ /\?/) ? "&id=$param{'id'}" : "?id=$param{'id'}";
+ }
+ $self->set_response($url, $refresh) or return;
+ return $self->parse_list_member_next();
+}
+
+sub get_list_member_previous {
+ my $self = shift;
+ my $url = 'list_member.pl';
+ $url = shift if (@_ and $_[0] ne 'refresh' and $_[0] ne 'id');
+ my $refresh = shift if (@_ and $_[0] eq 'refresh');
+ my %param = @_;
+ if (defined($param{'id'}) and length($param{'id'}) and $url !~ /[\?\&]id=/) {
+ $url .= ($url =~ /\?/) ? "&id=$param{'id'}" : "?id=$param{'id'}";
+ }
+ $self->set_response($url, $refresh) or return;
+ return $self->parse_list_member_previous();
+}
+
sub get_list_message {
my $self = shift;
my $url = 'list_message.pl';
@@ -1268,6 +1797,14 @@
return $self->parse_list_outbox();
}
+sub get_list_request {
+ my $self = shift;
+ my $url = 'list_request.pl';
+ $url = shift if (@_ and $_[0] ne 'refresh');
+ $self->set_response($url, @_) or return;
+ return $self->parse_list_request();
+}
+
sub get_new_album {
my $self = shift;
my $url = 'new_album.pl';
@@ -1308,9 +1845,56 @@
return $self->parse_new_comment();
}
-sub get_new_diary {
+sub get_new_friend_diary {
+ my $self = shift;
+ my $url = 'new_friend_diary.pl';
+ $url = shift if (@_ and $_[0] ne 'refresh');
+ $self->set_response($url, @_) or return;
+ return $self->parse_new_friend_diary();
+}
+
+sub get_new_friend_diary_next {
+ my $self = shift;
+ my $url = 'new_friend_diary.pl';
+ $url = shift if (@_ and $_[0] ne 'refresh');
+ $self->set_response($url, @_) or return;
+ return $self->parse_new_friend_diary_next();
+}
+
+sub get_new_friend_diary_previous {
+ my $self = shift;
+ my $url = 'new_friend_diary.pl';
+ $url = shift if (@_ and $_[0] ne 'refresh');
+ $self->set_response($url, @_) or return;
+ return $self->parse_new_friend_diary_previous();
+}
+
+sub get_new_review {
+ my $self = shift;
+ my $url = 'new_review.pl';
+ $url = shift if (@_ and $_[0] ne 'refresh');
+ $self->set_response($url, @_) or return;
+ return $self->parse_new_review();
+}
+
+sub get_release_info {
+ my $self = shift;
+ my $url = 'release_info.pl';
+ $url = shift if (@_ and $_[0] ne 'refresh');
+ $self->set_response($url, @_) or return;
+ return $self->parse_release_info();
+}
+
+sub get_self_id {
+ my $self = shift;
+ my $url = 'show_profile.pl';
+ $self->set_response($url, @_) or return;
+ return $self->parse_self_id();
+}
+
+sub get_search_diary {
my $self = shift;
- my $url = 'new_diary.pl';
+ my $url = 'search_diary.pl';
$url = shift if (@_ and $_[0] ne 'refresh' and $_[0] ne 'keyword');
my $refresh = shift if (@_ and $_[0] eq 'refresh');
my %param = @_;
@@ -1319,13 +1903,14 @@
$param{'keyword'} =~ tr/ /+/;
$url .= ($url =~ /\?/) ? "&keyword=$param{'keyword'}" : "?keyword=$param{'keyword'}";
}
- $self->set_response($url, $refresh) or return;
- return $self->parse_new_diary();
+ @_ = grep { defined($_) } ($url, $refresh);
+ $self->set_response(@_) or return;
+ return $self->parse_search_diary();
}
-sub get_new_diary_next {
+sub get_search_diary_next {
my $self = shift;
- my $url = 'new_diary.pl';
+ my $url = 'search_diary.pl';
$url = shift if (@_ and $_[0] ne 'refresh' and $_[0] ne 'keyword');
my $refresh = shift if (@_ and $_[0] eq 'refresh');
my %param = @_;
@@ -1335,12 +1920,12 @@
$url .= ($url =~ /\?/) ? "&keyword=$param{'keyword'}" : "?keyword=$param{'keyword'}";
}
$self->set_response($url, $refresh) or return;
- return $self->parse_new_diary_next();
+ return $self->parse_search_diary_next();
}
-sub get_new_diary_previous {
+sub get_search_diary_previous {
my $self = shift;
- my $url = 'new_diary.pl';
+ my $url = 'search_diary.pl';
$url = shift if (@_ and $_[0] ne 'refresh' and $_[0] ne 'keyword');
my $refresh = shift if (@_ and $_[0] eq 'refresh');
my %param = @_;
@@ -1350,46 +1935,47 @@
$url .= ($url =~ /\?/) ? "&keyword=$param{'keyword'}" : "?keyword=$param{'keyword'}";
}
$self->set_response($url, $refresh) or return;
- return $self->parse_new_diary_previous();
+ return $self->parse_search_diary_previous();
}
-sub get_new_friend_diary {
+sub get_show_calendar {
my $self = shift;
- my $url = 'new_friend_diary.pl';
+ my $url = 'show_calendar.pl';
$url = shift if (@_ and $_[0] ne 'refresh');
$self->set_response($url, @_) or return;
- return $self->parse_new_friend_diary();
+ return $self->parse_show_calendar();
}
-sub get_new_friend_diary_next {
+sub get_show_calendar_term {
my $self = shift;
- my $url = 'new_friend_diary.pl';
+ my $url = 'show_calendar.pl';
$url = shift if (@_ and $_[0] ne 'refresh');
$self->set_response($url, @_) or return;
- return $self->parse_new_friend_diary_next();
+ return $self->parse_show_calendar_term();
}
-sub get_new_friend_diary_previous {
+sub get_show_calendar_next {
my $self = shift;
- my $url = 'new_friend_diary.pl';
+ my $url = 'show_calendar.pl';
$url = shift if (@_ and $_[0] ne 'refresh');
$self->set_response($url, @_) or return;
- return $self->parse_new_friend_diary_previous();
+ return $self->parse_show_calendar_next();
}
-sub get_new_review {
+sub get_show_calendar_previous {
my $self = shift;
- my $url = 'new_review.pl';
+ my $url = 'show_calendar.pl';
$url = shift if (@_ and $_[0] ne 'refresh');
$self->set_response($url, @_) or return;
- return $self->parse_new_review();
+ return $self->parse_show_calendar_previous();
}
-sub get_self_id {
+sub get_show_intro {
my $self = shift;
- my $url = 'show_profile.pl';
+ my $url = 'show_intro.pl';
+ $url = shift if (@_ and $_[0] ne 'refresh');
$self->set_response($url, @_) or return;
- return $self->parse_self_id();
+ return $self->parse_show_intro();
}
sub get_show_log {
@@ -1408,20 +1994,75 @@
return $self->parse_show_log_count();
}
-sub get_show_show_friend_outline {
+sub get_show_friend_outline {
my $self = shift;
my $url = shift or return undef;
$self->set_response($url, @_) or return undef;
return $self->parse_show_friend_outline();
}
-sub get_show_show_friend_profile {
+sub get_show_friend_profile {
my $self = shift;
my $url = shift or return undef;
$self->set_response($url, @_) or return undef;
return $self->parse_show_friend_profile();
}
+sub get_view_album {
+ my $self = shift;
+ my $url = 'view_album.pl';
+ $url = shift if (@_ and $_[0] ne 'refresh' and $_[0] ne 'id');
+ my $refresh = shift if (@_ and $_[0] eq 'refresh');
+ my %param = @_;
+ if (defined($param{'id'}) and length($param{'id'}) and $url !~ /[\?\&]id=/) {
+ $url .= ($url =~ /\?/) ? "&id=$param{'id'}" : "?id=$param{'id'}";
+ }
+ return $self->get_standard_data('parse_view_album', qr/view_album\.pl/, $url, $refresh);
+}
+
+sub get_view_album_comment {
+ my $self = shift;
+ my $url = 'view_album.pl';
+ $url = shift if (@_ and $_[0] ne 'refresh' and $_[0] ne 'id');
+ my $refresh = shift if (@_ and $_[0] eq 'refresh');
+ my %param = @_;
+ if (defined($param{'id'}) and length($param{'id'}) and $url !~ /[\?\&]id=/) {
+ $url .= ($url =~ /\?/) ? "&id=$param{'id'}" : "?id=$param{'id'}&mode=comment";
+ }
+ return $self->get_standard_data('parse_view_album_comment', qr/view_album\.pl/, $url, $refresh);
+}
+
+sub get_view_album_photo {
+ my $self = shift;
+ my $url = 'view_album.pl';
+ $url = shift if (@_ and $_[0] ne 'refresh' and $_[0] ne 'id');
+ my $refresh = shift if (@_ and $_[0] eq 'refresh');
+ my %param = @_;
+ if (defined($param{'id'}) and length($param{'id'}) and $url !~ /[\?\&]id=/) {
+ $url .= ($url =~ /\?/) ? "&id=$param{'id'}" : "?id=$param{'id'}";
+ }
+ return $self->get_standard_data('parse_view_album_photo', qr/view_album\.pl/, $url, $refresh);
+}
+
+sub get_view_bbs {
+ my $self = shift;
+ my $url = shift or return;
+ $self->set_response($url, @_) or return undef;
+ return $self->parse_view_bbs();
+}
+
+sub get_view_community {
+ my $self = shift;
+ my $url = 'view_community.pl';
+ $url = shift if (@_ and $_[0] ne 'refresh' and $_[0] ne 'id');
+ my $refresh = shift if (@_ and $_[0] eq 'refresh');
+ my %param = @_;
+ if (defined($param{'id'}) and length($param{'id'}) and $url !~ /[\?\&]id=/) {
+ $url .= ($url =~ /\?/) ? "&id=$param{'id'}" : "?id=$param{'id'}";
+ }
+ return $self->get_standard_data('parse_view_community', qr/view_community\.pl/, $url, $refresh);
+}
+
sub get_view_diary {
my $self = shift;
my $url = shift or return;
@@ -1429,6 +2070,13 @@
return $self->parse_view_diary();
}
+sub get_view_event {
+ my $self = shift;
+ my $url = shift or return;
+ $self->set_response($url, @_) or return undef;
+ return $self->parse_view_event();
+}
+
sub get_view_message {
my $self = shift;
my $url = shift or return undef;
@@ -1541,8 +2189,9 @@
sub absolute_url {
my $self = shift;
my $url = shift;
- return undef unless ($url);
my $base = (@_) ? shift : $self->{'mixi'}->{'base'};
+ return undef unless (length($url));
+ $url =~ s/^"(.*)"$/$1/ or $url =~ s/^'(.*)'$/$1/;
$url .= '.pl' if ($url and $url !~ /[\/\.]/);
return URI->new($url)->abs($base)->as_string;
}
@@ -1551,8 +2200,7 @@
my $self = shift;
my $url = shift;
return $url unless ($url and $self->response());
- my $res = $self->response();
- my $base = $res->request->uri->as_string;
+ my $base = $self->response->base->as_string;
return $self->absolute_url($url, $base);
}
@@ -1665,7 +2313,7 @@
}
sub callback_abort {
- die;
+ die @_;
}
sub rewrite {
@@ -1678,6 +2326,7 @@
my $str = shift;
$str = $self->remove_tag($str);
$str = $self->unescape($str);
+ $str =~ s/\s+$//s;
return $str;
}
@@ -1695,12 +2344,7 @@
my $str = shift;
my %unescaped = ('amp' => '&', 'quot' => '"', 'gt' => '>', 'lt' => '<', 'nbsp' => ' ', 'apos' => "'", 'copy' => '(c)');
my $re_target = join('|', keys(%unescaped));
- $str =~ s[&(.*?);]{
- local $_ = lc($1);
- /^($re_target)$/ ? $unescaped{$1} :
- /^#x([0-9a-f]+)$/ ? chr(hex($1)) :
- $_
- }gex;
+ $str =~ s/&($re_target|#x([0-9a-z]+));/defined($unescaped{$1}) ? $unescaped{$1} : defined($2) ? chr(hex($2)) : "&$1;"/ige;
return $str;
}
@@ -1708,7 +2352,6 @@
my $self = shift;
my $str = shift;
my $re_standard_tag = q{[^"'<>]*(?:"[^"]*"[^"'<>]*|'[^']*'[^"'<>]*)*(?:>|(?=<)|$(?!\n))};
-# my $re_standard_tag = q{[^"'<>]*(?:"[^"]*"'?[^"'<>]*|'[^']*'"?[^"'<>]*)*(?:>|(?=<)|$(?!\n))}; # <a href='URL'">のような余計なダブルクォート対応
my $re_comment_tag = '<!(?:--[^-]*-(?:[^-]+-)*?-(?:[^>-]*(?:-[^>-]+)*?)??)*(?:>|$(?!\n)|--.*$)';
my $re_html_tag = qq{$re_comment_tag|<$re_standard_tag};
$str =~ s/$re_html_tag//g;
@@ -1734,6 +2377,24 @@
return 1;
}
+sub get_standard_data {
+ # default url is pased, so url is not necessary.
+ my $self = shift;
+ my $parser = shift;
+ my $def_url = shift; # defined url
+ my $url = shift if (@_ and $_[0] ne 'refresh'); # specified url
+ if (defined($def_url) and ref($def_url) eq 'Regexp') {
+ return unless (defined($url) and length($url));
+ return unless ($url =~ $def_url);
+ } elsif (not (ref($url) eq '' and length($url))) {
+ $url = $def_url;
+ }
+ $self->abort("url \"$url\" is invalid.") unless (defined($url) and length($url)); # invalid url
+ $self->can($parser) or $self->abort("parser \"$parser\" is not available."); # invalid method
+ $self->set_response($url, @_) or $self->abort("set_response failed."); # request can not processed
+ return $self->$parser();
+}
+
sub parse_standard_history {
my $self = shift;
my $res = (@_) ? shift : $self->response();
@@ -1742,21 +2403,37 @@
my $content = $res->content;
my @items = ();
my $re_date = '(?:(\d{4})年)?(\d{2})月(\d{2})日 (\d{1,2}):(\d{2})';
- my $re_name = '\(([^\r\n]*)\)';
- my $re_link = '<a href="?(.+?)"?>(.+?)\s*<\/a>';
+ my $re_link = '<a [^<>]*href="?([^<> ]*?)"?(?: [^<>]*)?>(.*?)<\/a>';
+ my $re_name = '\((.*?)\)';
if ($content =~ /<table BORDER=0 CELLSPACING=1 CELLPADDING=4 WIDTH=630>(.+?)<\/table>/s) {
$content = $1;
my @today = reverse((localtime)[3..5]);
$today[0] += 1900;
$today[1] += 1;
- while ($content =~ s/<tr bgcolor=#FFFFFF>.*?${re_date}.*?${re_link}\s*${re_name}.*?<\/tr>//is) {
- my @date = ($1, $2, $3, $4, $5);
- $date[0] = ($date[1] > $today[1]) ? $today[0] - 1 : $today[0] if (not defined($date[0]));
- my $time = sprintf('%04d/%02d/%02d %02d:%02d', @date);
- my $subj = $self->rewrite($7);
- my $name = $self->rewrite($8);
- my $link = $self->absolute_url($6, $base);
- push(@items, {'time' => $time, 'subject' => $subj, 'name' => $name, 'link' => $link});
+ foreach my $row ($content =~ /<tr bgcolor=#FFFFFF>(.*?)<\/tr>/isg) {
+ $row =~ s/\s*[\r\n]\s*//gs;
+ my @cols = ($row =~ /<td[^<>]*>(.*?)<\/td>/gs);
+ my $item = {};
+ next unless ($cols[0] =~ s/$re_date//);
+ my @date = ($1, $2, $3, $4, $5);
+ next unless ($cols[1] =~ /${re_link}\s*$re_name/);
+ $item->{'link'} = $self->absolute_url($1, $base);
+ $item->{'subject'} = (defined($2) and length($2)) ? $self->rewrite($2) : '(削除)';
+ $item->{'name'} = $self->rewrite($3);
+ $date[0] = ($date[1] > $today[1]) ? $today[0] - 1 : $today[0] if (not defined($date[0]));
+ $item->{'time'} = sprintf('%04d/%02d/%02d %02d:%02d', @date);
+ map { $item->{$_} =~ s/^\s+|\s+$//gs } (keys(%{$item}));
+ if ($cols[1] =~ /(<a [^>]*>)\s*(<img [^>]*>)\s*<\/a>/is) {
+ my $image = {};
+ my @tags = ($1, $2);
+ if ($_ = $self->parse_standard_tag($tags[0]) and $_->{'attr'}->{'href'} or $_->{'attr'}->{'onclick'}) {
+ $_ = ($_->{'attr'}->{'onclick'}) ? $_->{'attr'}->{'onclick'} : $_->{'attr'}->{'href'};
+ $_ = $1 if ($_ =~ /MM_openBrWindow\('(.*?)'/);
+ $item->{'image'}->{'link'} = $self->absolute_url($_, $base);
+ }
+ $item->{'image'}->{'src'} = $self->absolute_url($_, $base) if ($_ = $self->parse_standard_tag($tags[1]) and $_ = $_->{'attr'}->{'src'});
+ }
+ push(@items, $item);
}
}
return @items;
@@ -1826,11 +2503,26 @@
return @items;
}
+sub parse_standard_tag {
+ my $self = shift;
+ my $str = shift;
+ return undef unless ($str =~ s/^\s*<(.*)>\s*$/$1/s);
+ return undef if ($str =~ /^\!--/);
+ my $re_word = q{[^"'<>\s=]+}; #"]}
+ my $re_quote = q{(?:"[^"]*"|'[^']*')}; #")}
+ my $re_pair = qq{$re_word\\s*=\\s*(?:$re_quote|$re_word\\((?:[^)]*|$re_quote)*\\)|[^"'<>\\s]+)?};
+ my $re_parse = qq{$re_pair|$re_word|$re_quote};
+ my @parsed = ($str =~ /$re_parse/gs);
+ my $tag = lc(shift(@parsed));
+ @parsed = map { /^($re_word)\s*=\s*(.*)$/ ? (lc($1) => $2) : (lc($_) => '') } @parsed;
+ @parsed = map { /^\s*=\s*$/ ? '=' :/^"(.*)"$/ ? $1 : /^'(.*)'$/ ? $1 : $_ } @parsed;
+ return { 'tag' => $tag, , 'attr' => {@parsed} };
+}
sub set_response {
my $self = shift;
my $url = shift;
- my $refresh = (@_ and $_[0] eq 'refresh') ? 1 : 0;
+ my $refresh = (@_ and defined($_[0]) and $_[0] eq 'refresh') ? 1 : 0;
my $latest = ($self->response) ? $self->response->request->uri->as_string : undef;
$url = $self->query_sorted_url($self->absolute_url($url));
return 0 unless ($url);
@@ -1875,12 +2567,11 @@
my $self = shift;
my %values = @_;
$self->dumper_log(\%values);
- $values{'id'} = $values{'diary_id'} if (not $values{'id'} and defined($values{'diary_id'}));
my $url = exists($values{'__action__'}) ? $values{'__action__'} : 'edit_diary.pl?id=' . $values{'id'};
- my @fields = qw(submit diary_title diary_body photo1 photo2 photo3 submit);
+ my @fields = qw(submit diary_title diary_body photo1 photo2 photo3 submit post_key);
my @required = qw(submit diary_title diary_body);
my @files = qw(photo1 photo2 photo3);
- my %label = ('id' => '日記ID', 'diary_title' => '日記のタイトル', 'diary_body' => '日記の本文', 'photo1' => '写真1', 'photo2' => '写真2', 'photo3' => '写真3');
+ my %label = ('id' => '日記ID', 'diary_title' => '日記のタイトル', 'diary_body' => '日記の本文', 'photo1' => '写真1', 'photo2' => '写真2', 'photo3' => '写真3', 'post_key' => '送信キー');
my @errors;
# データの生成とチェック
my %form = map { $_ => $values{$_} } @fields;
@@ -1911,7 +2602,6 @@
my %label = ('id' => '日記ID', 'post_key' => '送信キー');
# データの生成とチェック
my %form = map {$_ => $values{$_}} @fields;
- $form{'id'} = $values{'diary_id'} if (not $form{'id'} and defined($values{'diary_id'}));
$form{'id'} = $1 if ($values{'__action__'} and $values{'__action__'} =~ /delete_diary.pl?id=(\d+)/);
my @errors = map { "$label{$_}を指定してください。" } grep { not $form{$_} } @required;
if (@errors) {
@@ -1944,9 +2634,9 @@
my $self = shift;
my $time = @_ ? shift : 0;
if ($time =~ /^\d+$/) { 1; }
- elsif ($time =~ /^(\d+)分/) { $time = $time * 60; }
- elsif ($time =~ /^(\d+)時間/) { $time = $time * 60 * 60; }
- elsif ($time =~ /^(\d+)日/) { $time = $time * 60 * 60 * 24; }
+ elsif ($time =~ /^(\d+)分/) { $time = $1 * 60; }
+ elsif ($time =~ /^(\d+)時間/) { $time = $1 * 60 * 60; }
+ elsif ($time =~ /^(\d+)日/) { $time = $1 * 60 * 60 * 24; }
else { $self->log("[error] ログイン時刻\"$time\"を解析できませんでした。\n"); }
$time = time() - $time;
my @date = localtime($time);
@@ -1975,16 +2665,12 @@
my $mixi = &test_new($mail, $pass, $logger); # オブジェクトの生成
$mixi->test_login; # ログイン
$mixi->test_get; # GET(トップページ)
- $mixi->test_get_main_menu; # メインメニューの解析
- $mixi->test_get_banner; # バナーの解析
- $mixi->test_get_tool_bar; # ツールバーの解析
- $mixi->test_get_mainly_categories; # 主要データの取得と解析
- $mixi->test_get_mainly_categories_pagelinks; # 主要データの次のページと前のページ
- $mixi->test_get_details; # 詳細表示(view_〜など)の取得と解析
+ $mixi->test_scenario; # 主要データの取得と解析
$mixi->test_get_add_diary_preview; # 日記のプレビュー
$mixi->test_save_and_read_cookies; # Cookieの読み書き
# 終了
$mixi->log("終了しました。\n");
+ $mixi->dumper_log({'テストレコード' => $mixi->{'__test_record'}, 'テストリンク' => $mixi->{'__test_link'}});
exit 0;
}
@@ -2080,183 +2766,133 @@
}
}
-sub test_get_main_menu {
- my $mixi = shift;
- my $error = '';
- $mixi->log("メインメニューの解析をします。\n");
- my @items = eval '$mixi->get_main_menu()';
- if ($@) {
- $error = "[error] $@\n";
- } elsif (not @items) {
- $error = "[error] メニュー項目が見つかりませんでした。\n";
- }
- if ($error) {
- $mixi->log("メインメニューの解析に失敗しました。\n", $error);
- $mixi->dumper_log($mixi->response);
- exit 8;
- } else {
- $mixi->dumper_log([@items]);
- }
-}
-
-sub test_get_banner {
+sub test_record {
my $mixi = shift;
- my $error = '';
- $mixi->log("バナーの解析をします。\n");
- my @items = eval '$mixi->get_banner()';
- if ($@) {
- $error = "[error] $@\n";
- } elsif (not @items) {
- $error = "[error] バナーが見つかりませんでした。\n";
- }
- if ($error) {
- $mixi->log("バナーの解析に失敗しました。\n", $error);
- $mixi->dumper_log($mixi->response);
- exit 8;
+ $mixi->{'__test_record'} = {} unless (ref($mixi->{'__test_record'}) eq 'HASH');
+ if (@_ == 0) {
+ return sort { $a cmp $b } (keys(%{$mixi->{'__test_record'}}));
+ } elsif (@_ == 1) {
+ my $key = shift;
+ return $mixi->{'__test_record'}->{$key};
} else {
- $mixi->dumper_log([@items]);
+ my %args = @_;
+ map { $mixi->{'__test_record'}->{$_} = $args{$_} } keys(%args);
+ return 1;
}
}
-sub test_get_tool_bar {
+sub test_link {
my $mixi = shift;
- my $error = '';
- $mixi->log("ツールバーの解析をします。\n");
- my @items = eval '$mixi->get_tool_bar()';
- if ($@) {
- $error = "[error] $@\n";
- } elsif (not @items) {
- $error = "[error] ツールバー項目が見つかりませんでした。\n";
- }
- if ($error) {
- $mixi->log("ツールバーの解析に失敗しました。\n", $error);
- $mixi->dumper_log($mixi->response);
- exit 8;
+ $mixi->{'__test_link'} = {} unless (ref($mixi->{'__test_link'}) eq 'HASH');
+ if (@_ == 0) {
+ return sort { $a cmp $b } (keys(%{$mixi->{'__test_link'}}));
+ } elsif (@_ == 1) {
+ my $key = shift;
+ return $mixi->{'__test_link'}->{$key};
} else {
- $mixi->dumper_log([@items]);
- }
-}
-
-sub test_get_mainly_categories {
- my $mixi = shift;
- my %categories = (
- 'calendar' => 'カレンダー',
- 'calendar_term' => 'カレンダーの期間',
- 'information' => '管理者からのお知らせ',
- 'list_bookmark' => 'お気に入り',
- 'list_comment' => '最近のコメント',
- 'list_community' => 'コミュニティ一覧',
- 'list_diary' => '日記',
- 'list_diary_capacity' => '日記容量',
- 'list_diary_monthly_menu' => '日記月別ページ',
- 'list_friend' => '友人・知人一覧',
- 'list_message' => '受信メッセージ',
- 'list_outbox' => '送信メッセージ',
- 'new_album' => 'マイミクシィ最新アルバム',
- 'new_bbs' => 'コミュニティ最新書き込み',
- 'new_comment' => '日記コメント記入履歴',
- 'new_diary' => '新着日記検索',
- 'new_friend_diary' => 'マイミクシィ最新日記',
- 'new_review' => 'マイミクシィ最新レビュー',
- 'self_id' => '自分のID',
- 'show_log' => 'あしあと',
- 'show_log_count' => 'あしあと数',
- );
- foreach my $category (sort(keys(%categories))) {
- $mixi->log($categories{$category} . "の取得と解析をします。\n");
- my @opt = ($category eq 'new_diary') ? ('keyword' => 'Mixi') : ();
- my @items = eval "\$mixi->get_${category}(\@opt)";
- my $error = ($@) ? $@ : ($mixi->response->is_error) ? $mixi->response->status_line : undef;
- if (defined $error) {
- $mixi->log("${category}の取得と解析に失敗しました。\n", "[error] $error\n");
- $mixi->dumper_log($mixi->response);
- exit 8;
- } else {
- if (@items) {
- $mixi->dumper_log([@items]);
- $mixi->{'__test_record'}->{$category} = $items[0];
- } else {
- $mixi->log("[warn] レコードが見つかりませんでした。\n");
- $mixi->dumper_log($mixi->response);
+ my $key = shift;
+ foreach my $item (grep { ref($_) eq 'HASH' } @_) {
+ foreach (values(%{$item})) {
+ foreach my $value (ref($_) eq 'HASH' ? values(%{$_}) : $_) {
+ next if (ref($value) ne '' or $value =~ /\s/);
+ next if ($value !~ /^https?:\/\/(?:[^\/]*].)?mixi.jp\/(?:[^\?]*\/)?([^\/\?]+).*$/);
+ next if ($mixi->{'__test_link'}->{$1});
+ $mixi->{'__test_link'}->{$1} = $value;
+ }
}
}
+ return 1;
}
}
-sub test_get_mainly_categories_pagelinks {
- my $mixi = shift;
- my %categories = (
- 'calendar' => 'カレンダー',
- 'list_community' => 'コミュニティ一覧',
- 'list_diary' => '日記',
- 'list_friend' => '友人・知人一覧',
- 'new_bbs' => 'コミュニティ最新書き込み',
- 'new_diary' => '新着日記検索',
- 'new_friend_diary' => 'マイミクシィ最新日記',
- );
- foreach my $category (sort(keys(%categories))) {
- my @opt = ($category eq 'new_diary') ? ('keyword' => 'Mixi') : ();
- my $error = '';
- $mixi->log($categories{$category} . "の次のページへのリンクの解析をします。\n");
- my $next = eval "\$mixi->get_${category}_next(\@opt)";
- if ($@) {
- $error = "[error] $@\n";
- } elsif ($mixi->response->is_error) {
- $error = "[error] " . $mixi->response->status_line ."\n";
- } elsif (not $next) {
- $mixi->log("[warn] 次のページが見つかりませんでした。\n");
- $mixi->dumper_log($mixi->response);
- } else {
- $mixi->dumper_log($next);
- }
- if ($error) {
- $mixi->log($error);
- $mixi->dumper_log($mixi->response);
- exit 8;
- }
- $mixi->log($categories{$category} . "の前のページへのリンクの解析をします。\n");
- if (not $next) {
- $mixi->log("[info] 次のページがなかったため、スキップされました。\n");
- next;
- }
- my $previous = eval "\$mixi->get_${category}_previous(\$next->{'link'})";
- if ($@) {
- $error = "[error] $@\n";
- } elsif ($mixi->response->is_error) {
- $error = "[error] " . $mixi->response->status_line ."\n";
- } elsif (not $previous) {
- $mixi->log("[warn] 前のページが見つかりませんでした。\n");
- $mixi->dumper_log($mixi->response);
- } else {
- $mixi->dumper_log($previous);
- }
- if ($error) {
- $mixi->log($error);
- $mixi->dumper_log($mixi->response);
- exit 8;
- }
- }
-}
-
-sub test_get_details {
+sub test_scenario {
my $mixi = shift;
- my %methods = (
- 'get_view_diary' => ['list_diary', '日記'],
- 'get_view_message' => ['list_message', 'メッセージ'],
- 'get_view_message_form' => ['list_message', 'メッセージ返信・削除フォーム'],
- 'get_show_show_friend_outline' => ['list_friend', 'プロフィール(概要)'],
- 'get_show_show_friend_profile' => ['list_friend', 'プロフィール(詳細)'],
+ my @tests = (
+ # 引数不要のもの
+ 'main_menu' => {'label' => 'メインメニュー'},
+ 'banner' => {'label' => 'バナー'},
+ 'tool_bar' => {'label' => 'ツールバー'},
+ 'information' => {'label' => '管理者からのお知らせ'},
+ 'home_new_album' => {'label' => 'ホームのマイミクシィ最新アルバム'},
+ 'home_new_bbs' => {'label' => 'ホームのコミュニティ最新書き込み'},
+ 'home_new_comment' => {'label' => 'ホームの日記コメント記入履歴'},
+ 'home_new_friend_diary' => {'label' => 'ホームのマイミクシィ最新日記'},
+ 'home_new_review' => {'label' => 'ホームのマイミクシィ最新レビュー'},
+ 'list_bookmark' => {'label' => 'お気に入り'},
+ 'list_comment' => {'label' => '最近のコメント'},
+ 'list_community' => {'label' => 'コミュニティ一覧'},
+ 'list_community_next' => {'label' => 'コミュニティ一覧(次)'},
+ 'list_community_previous' => {'label' => 'コミュニティ一覧(前)', 'url' => sub { return $_[0]->test_record('list_community_next')}},
+ 'list_diary' => {'label' => '日記'},
+ 'list_diary_capacity' => {'label' => '日記容量'},
+ 'list_diary_next' => {'label' => '日記(次)'},
+ 'list_diary_previous' => {'label' => '日記(前)', 'url' => sub { return $_[0]->test_record('list_diary_next')}},
+ 'list_diary_monthly_menu' => {'label' => '日記月別ページ'},
+ 'list_friend' => {'label' => '友人・知人一覧'},
+ 'list_friend_next' => {'label' => '友人・知人一覧(次)'},
+ 'list_friend_previous' => {'label' => '友人・知人一覧(前)', 'url' => sub { return $_[0]->test_record('list_friend_next')}},
+ 'list_message' => {'label' => '受信メッセージ'},
+ 'list_outbox' => {'label' => '送信メッセージ'},
+ 'list_request' => {'label' => '承認待ちの友人'},
+ 'new_album' => {'label' => 'マイミクシィ最新アルバム'},
+ 'new_bbs' => {'label' => 'コミュニティ最新書き込み'},
+ 'new_bbs_next' => {'label' => 'コミュニティ最新書き込み(次)'},
+ 'new_bbs_previous' => {'label' => 'コミュニティ最新書き込み(前)', 'url' => sub { return $_[0]->test_record('new_bbs_next')}},
+ 'new_comment' => {'label' => '日記コメント記入履歴'},
+ 'new_friend_diary' => {'label' => 'マイミクシィ最新日記'},
+ 'new_friend_diary_next' => {'label' => 'マイミクシィ最新日記(次)'},
+ 'new_friend_diary_previous' => {'label' => 'マイミクシィ最新日記(前)', 'url' => sub { return $_[0]->test_record('new_friend_diary_next')}},
+ 'ajax_new_diary' => {'label' => 'マイミクシィの最新日記(Ajax版)', 'url' => sub { return $_[0]->test_link('ajax_new_diary.pl') }},
+ 'new_review' => {'label' => 'マイミクシィ最新レビュー'},
+ 'release_info' => {'label' => 'リリースインフォメーション'},
+ 'self_id' => {'label' => '自分のID'},
+ 'search_diary' => {'label' => '新着日記検索', 'arg' => ['keyword' => 'Mixi']},
+ 'search_diary_next' => {'label' => '新着日記検索(次)', 'arg' => ['keyword' => 'Mixi']},
+ 'search_diary_previous' => {'label' => '新着日記検索(前)', 'url' => sub { return $_[0]->test_record('search_diary_next')}},
+ 'show_calendar' => {'label' => 'カレンダー'},
+ 'show_calendar_term' => {'label' => 'カレンダーの期間'},
+ 'show_calendar_next' => {'label' => 'カレンダー(次)'},
+ 'show_calendar_previous' => {'label' => 'カレンダー(前)', 'url' => sub { return $_[0]->test_record('show_calendar_next')}},
+ 'show_intro' => {'label' => 'マイミクシィからの紹介文'},
+ 'show_log' => {'label' => 'あしあと'},
+ 'show_log_count' => {'label' => 'あしあと数'},
+ # コンテンツ
+ 'view_album' => {'label' => 'フォトアルバム', 'url' => sub { return $_[0]->test_record('new_album')}},
+ 'view_album_photo' => {'label' => 'フォトアルバムの写真', 'url' => sub { $_ = $_[0]->test_record('new_album'); return ref($_) eq 'HASH' ? $_->{'link'} : undef }},
+ 'view_album_comment' => {'label' => 'フォトアルバムのコメント', 'url' => sub { $_ = $_[0]->test_record('new_album'); return ref($_) eq 'HASH' ? $_->{'link'} . '&mode=comment' : undef }},
+ 'view_diary' => {'label' => '日記(詳細)', 'url' => sub { return $_[0]->test_record('list_diary')}},
+ 'view_event' => {'label' => 'イベント', 'url' => sub { return $_[0]->test_link('view_event.pl')}},
+ 'view_message' => {'label' => 'メッセージ(詳細)', 'url' => sub { return $_[0]->test_record('list_message')}},
+ # コミュニティ関連
+ 'community_id' => {'label' => 'コミュニティID', 'url' => sub { return $_[0]->test_record('list_community')}},
+ 'list_bbs' => {'label' => 'トピック一覧', 'arg' => ['id' => sub { return $_[0]->test_record('community_id')}]},
+ 'list_bbs_next' => {'label' => 'トピック一覧(次)', 'arg' => ['id' => sub { return $_[0]->test_record('community_id')}]},
+ 'list_bbs_previous' => {'label' => 'トピック一覧(前)', 'url' => sub { return $_[0]->test_record('list_bbs_next')}},
+ 'list_member' => {'label' => 'メンバー一覧', 'arg' => ['id' => sub { return $_[0]->test_record('community_id')}]},
+ 'list_member_next' => {'label' => 'メンバー一覧(次)', 'arg' => ['id' => sub { return $_[0]->test_record('community_id')}]},
+ 'list_member_previous' => {'label' => 'メンバー一覧(前)', 'url' => sub { return $_[0]->test_record('list_member_next')}},
+ 'view_bbs' => {'label' => 'トピック', 'url' => sub { return $_[0]->test_record('list_bbs')}},
+# 'view_community' => {'label' => 'コミュニティ', 'arg' => ['id' => sub { return $_[0]->test_record('community_id')}]},
);
- foreach my $method (sort(keys(%methods))) {
- my ($category, $label) = @{$methods{$method}};
- my $item = $mixi->{'__test_record'}->{$category};
- unless ($item) {
- $mixi->log("[info] ${label}は対象レコードがないためスキップされました。\n");
- next;
+ while (@tests >= 2) {
+ my ($test, $opt) = splice(@tests, 0, 2);
+ my $method = "get_$test";
+ my $label = $opt->{'label'};
+ my $url = defined($opt->{'url'}) ? $opt->{'url'} : '';
+ if (defined($url) and ref($url) eq 'CODE') {
+ $url = &{$url}($mixi);
+ unless ($url) {
+ $mixi->log("$labelをスキップします。\n", "[warn] 参照レコードなし\n");
+ next;
+ }
}
- my $link = $item->{'link'};
+ $url = $url->{'link'} if (defined($url) and ref($url) eq 'HASH');
+ my @arg = (defined($opt->{'arg'}) and ref($opt->{'arg'})) eq 'ARRAY' ? @{$opt->{'arg'}} : ();
+ @arg = map { ref($_) eq 'CODE' ? &{$_}($mixi) : $_ } @arg;
+ unshift(@arg, $url) if (defined($url) and ref($url) eq '' and length($url));
$mixi->log("$labelの取得と解析をします。\n");
- my @items = eval "\$mixi->$method(\$link)";
+ $mixi->log(qq([info] ターゲットURLは"$url"です。\n));
+ my @items = eval { $mixi->$method(@arg); };
my $error = ($@) ? $@ : ($mixi->response->is_error) ? $mixi->response->status_line : undef;
if (defined $error) {
$mixi->log("$labelの取得と解析に失敗しました。\n", "[error] $error\n");
@@ -2265,8 +2901,11 @@
} else {
if (@items) {
$mixi->dumper_log([@items]);
+ $mixi->test_link($test => @items);
+ $mixi->test_record($test => $items[0]);
+ $mixi->test_record($test => {'link' => 'http://mixi.jp/view_album.pl?id=150828'}) if ($test eq 'new_album');
} else {
- $mixi->log("[info] レコードが見つかりませんでした。\n");
+ $mixi->log("[warn] レコードが見つかりませんでした。\n");
$mixi->dumper_log($mixi->response);
}
}
@@ -2339,7 +2978,7 @@
require WWW::RobotRules;
@ISA = qw(WWW::RobotRules::InCore);
-$VERSION = sprintf("%d.%02d", q$Revision: 1.4 $ =~ /(\d+)\.(\d+)/);
+$VERSION = sprintf("%d.%02d", q$Revision: 1.5 $ =~ /(\d+)\.(\d+)/);
sub allowed {
return 1;