package Plagger::Plugin::Notify::Pizza;
use strict;
use base qw( Plagger::Plugin );
use Plagger::Mechanize;
our %category = (
bento => '01',
pizza => '02', # default
sushi => '03',
chinese => '04',
european => '05',
curry => '11',
);
sub register {
my ($self, $context) = @_;
$context->register_hook(
$self,
'publish.feed' => \&deliver,
);
$self->{hungry} = 1;
}
sub deliver {
my ($self, $context, $args) = @_;
return unless $self->{hungry}; # I'm not hungry.
return unless $self->conf->{order}; # don't want order.
my $mech = new Plagger::Mechanize;
$self->{hungry} = 0;
# access...
$context->log(info => "Going to Demae-Can...");
$mech->get('http://demae-can.com/index.php?action=dream_login_index');
unless ($mech->success) {
$context->log(error => "Connect faled.");
return;
}
# login...
$mech->field('id' => $self->conf->{username});
$mech->field('pass' => $self->conf->{password});
$mech->click;
if ($mech->content !~ m{http://demae-can.com/search/shop_list.html\?word=0}) {
$context->log(error => "Login failed.(id=$self->conf->{username})");
print $mech->content;
return;
}
# select deliver-to
my $deliver_to = $self->conf->{deliver_to} || 0;
$mech->get("/search/shop_list.html?word=$deliver_to");
unless ($mech->success) {
$context->log(error => "Can't find group list.(deliver_to=$deliver_to)");
print $mech->content;
return;
}
my $shopcode;
if ($self->conf->{shopcode}) {
$shopcode = $self->conf->{shopcode};
$context->log(info => "Select shop.(shopcode=$shopcode)");
} else {
# select category...
my $cate = $category{ $self->conf->{category} || 'pizza' };
$context->log(info => "Select category.(category_id=$cate)");
unless ($mech->follow_link(url_regex => qr{shop_list2\.html\?cate=${cate}&code=\d+&mode=0})) {
$context->log(error => "Can't find shop list.(category_id=$cate)");
print $mech->content;
return;
}
if ($mech->content =~ m{
log(error => "Can't find shop.");
print $mech->content;
return;
}
}
# get menu...
$mech->get("/order/disp_menu.html?shopcode=${shopcode}&noid=&groupe=1");
unless ($mech->success) {
$context->log(error => "Can't find menu.(shopcode=$shopcode)");
print $mech->content;
return;
}
# choice item
my $itemcode;
$mech->form_number(1);
if ($self->conf->{itemcode}) {
$itemcode = $self->conf->{itemcode};
$mech->field('itemcode[0]' => $itemcode);
} else {
$itemcode = $mech->value('itemcode[0]');
}
$mech->click;
$context->log(info => "Select item.(itemcode=$itemcode)");
unless ($mech->success) {
$context->log(error => "Can't open item.");
print $mech->content;
return;
}
# order...
my $order = $self->conf->{order};
$context->log(info => "Order.(order=$order)");
$mech->form_number(1);
$mech->field('order_num', $order);
$mech->click;
unless ($mech->success) {
$context->log(error => "Can't go to cart.");
print $mech->content;
return;
}
# confirm...
$mech->form_number(1);
$mech->click;
unless ($mech->success) {
$context->log(error => "Can't go to confirm view.");
print $mech->content;
return;
}
if ($self->conf->{test}) { # stop.
print $mech->content;
$context->log(info => "test=1, not order.");
return;
}
# submit!
$mech->field('pass', $self->conf->{password});
$mech->click;
if ($mech->success) {
$context->log(info => join '',
"Order successfly.(",
"deliver_to=$deliver_to,",
"shopcode=$shopcode,",
"itemcode=$itemcode,",
"order=$order)"
);
} else {
$context->log(error => "Can't order.");
return;
}
}
1;
__END__
=encoding utf8
=head1 NAME
Plagger::Plugin::Notify::Pizza - Notify feed by pizza delivery boy
=head1 SYNOPSIS
- module: Notify::Pizza
config:
username: yourid@example.com
password: p4ssw0rd
order: 1
=head1 DESCRIPTION
It's joke module, but it works. So, USE AT YOUR OWN RISK.
=head1 CONFIGURATION
=over 4
=item username, password
Set your demae-can.com's ID & pass
=item order
You should set order number. Defalut is 0, that mean "not order."
=item category
With this option set, you can set the food types.
bento
pizza
sushi
chinese
european
curry
Default: pizza (year, of cource!)
=item shopcode, itemcode
You can set demae-can.com's shopcode and itemcode. You should scrapeing
demae-can.com's HTML to get this internal code.
=item test
This is important flag. If set 1, Notify::Pizza will not order submit.
=back
=head1 SAMPLE
I want Sushi. and surprise me!
- module: Notify::Pizza
config:
username: hungry@example.com
password: p4ssw0rd
category: shushi
order: 1
I know what I want.
- module: Notify::Pizza
config:
username: hungry@example.com
password: p4ssw0rd
shopcode: G115_107
itemcode: 102d
order: 2
=head1 HUNGRY_TO_PIZZA RECIPE
Googleに「はらへった」と検索するとピザが届くサンプルをご紹介します。
global:
user_agent:
agent: Mozilla/5.0
timezone: Asia/Tokyo
log:
level: debug
plugins:
- module: Subscription::Config
config:
feed: https://www.google.com/searchhistory/?output=rss
- module: UserAgent::AuthenRequest
config:
host: www.google.com:443
auth: basic
realm: Google Search History
username: your-google-id
password: your-google-password
plugins:
- module: CustomFeed::GoogleSearchHistory
config:
username: google-id
password: p4ssw0rd
- module: Filter::BreakEntriesToFeeds
config:
use_entry_title: 1
- module: Filter::Rule
rule:
- module: Deduped
- module: Fresh
duration: 10
- module: Notify::Pizza
rule:
expression: $args->{feed}->title =~ /^はらへった/
config:
username: my-demae-can-id
password: p4ssw0rd
order: 1
test: 1
詳しくは、L,
L,
Lを参照ください。
=head1 DEBUG
Notify::Pizza flush page content html to STDOUT. So, you can use this.
./plagger -c hungry.yaml > /var/www/scrape_test_dir/hungry.html
=head1 AUTHOR
Naoki Tomita Etomi@e8y.netE
=head1 SEE ALSO
L, L, L
=cut