#!/usr/bin/perl
-package Mubot4FB;
-
+#
+# Copyright (c) 2012 ISHIKAWA Mutsumi <ishikawa@hanzubon.jp>
+# This program is covered by the GNU General Public License 2
+#
use strict;
use utf8;
-use Facebook::Graph;
-use Bot::BasicBot;
-use base 'Bot::BasicBot';
-use Encode;
-use DBI;
-use POSIX 'strftime';
-
-use Data::Dumper;
-
-my $mu_re = qr/^([^ ]+) (https?:\/\/[^ ]+) (.+)$/i;
-
-sub fb_init {
- my ($me) = @_;
- my $fb = Facebook::Graph->new(app_id => $me->{cfg}->{fb_app_id},
- secret => $me->{cfg}->{fb_app_secret},
- postback => $me->{cfg}->{fb_postback_url});
-
- my $res_token = $fb->request_access_token($me->{cfg}->{fb_access_code});
- die 'token get error' if (!defined $res_token || !$res_token->response->is_success);
-
- my $acts = $fb->fetch('me/accounts');
- die 'can not get account list' if(!defined $acts || !$acts);
-
- my $page_access_token = '';
- foreach my $d (@{$acts->{data}}) {
- if ($d->{id} eq $me->{cfg}->{fb_page_id}) {
- $page_access_token = $d->{'access_token'};
- }
- }
- die 'can not get access tokenfor page_id=' . $me->{cfg}->{fb_page_id} if ($page_access_token eq '');
-
- return $me->{fbo} = Facebook::Graph->new(access_token => $page_access_token);
-}
-
-sub db_init {
- my ($me) = @_;
- $me->{dbh} = DBI->connect('dbi:SQLite:dbname='.$me->{cfg}->{database}) || die $DBI::errstr;
-}
-
-sub publish {
- my ($me, $text, $uri) = @_;
-
- return $me->{fbo}->add_post($me->{cfg}->{fb_page_id})
- ->set_message($text)
- ->set_link_uri($uri)
- ->publish()
- ->as_hashref();
-}
-
-sub init {
- my ($me) = @_;
- $me->fb_init();
- $me->db_init();
-}
-
-sub _check_dup {
- my ($me, $args, $uri) = @_;
-
- my $found = 0;
-
- my $sth = $me->{dbh}->prepare('select * from posts where uri = ? order by post_time desc limit 1');
- my $rv = $sth->execute($uri);
- my $res = $sth->fetchrow_hashref;
- if ($res) {
- if ($res->{post_time} < time() - 7 * 24 * 60 * 60) {
- $me->_response($args, 'だいぶ前に'.decode('utf-8', $res->{nick}).'が「'.decode('utf-8' $res->{prefix}).','.decode('utf-8', $res->{suffix}).'」とかいってたにゃー '.$me->{cfg}->{fb_page_url}.'posts/'.$res->{fb_post_id});
- } else {
- $me->_response($args, '既に'.decode('utf-8', $res->{nick}).'が「'.decode('utf-8', $res->{prefix}).','.decode('utf-8', $res->{suffix}).'」と'.strftime('%Y-%m-%d %H:%M:%S', localtime($res->{post_time})).'に言ってますよ? '.$me->{cfg}->{fb_page_url}.'posts/'.$res->{fb_post_id});
- $found = 1;
- }
- }
- $sth->finish;
-
- return $found;
-};
-
-sub _db_insert {
- my ($me, $db_args) = @_;
-
- my $sth = $me->{dbh}->prepare("insert into posts (id, nick, fb_post_id, uri, prefix, suffix, post_time) values (null, ?, ?, ?, ?, ?, ?)");
- my $rv = $sth->execute($db_args->{nick}, $db_args->{fb_post_id}, $db_args->{uri}, $db_args->{prefix}, $db_args->{suffix}, time);
- $sth->finish;
-
- return $rv;
-}
-
-sub _response {
- my ($me, $args, $msg) = @_;
-
- $me->say(channel => $args->{channel},
- body => $msg);
-}
-
-sub _add {
- my ($me, $args) =@_;
- my $post_ok = 1;
- my ($resp, $resp_msg);
+use Config::Any;
+use Hash::Merge::Simple;
+use Data::Recursive::Encode;
- if ($args->{body} =~ /$mu_re/) {
- my $prefix = $1;
- my $uri = $2;
- my $suffix = $3;
- my $text = $args->{who} . '曰く、'.$prefix.' '.$suffix;
+use FindBin;
+use lib ("$FindBin::Bin/lib", '/usr/share/keitairc/lib');
- return 0 if ($me->_check_dup($args, $uri));
+use Mubot4FB;
- eval{$resp = $me->publish($text, $uri)};
- if ($@) {
- $me->fb_init();
- eval{$resp = $me->publish($text, $uri)};
- $post_ok = 0 if ($@);
- }
-
- if ($post_ok) {
- my (undef, $post_id) = split(/_/, $resp->{id});
- $me->_db_insert({nick => $args->{who},
- fb_post_id => $post_id,
- uri => $uri,
- prefix => $prefix,
- suffix => $suffix});
- $resp_msg = 'うい: ' . $me->{cfg}->{fb_page_url} . 'posts/' . $post_id .' で登録';
- } else {
- $resp_msg = 'can not post to facebook';
- }
-
- return $resp_msg;
- }
- return 0;
-}
-
-sub _delete_prev {
- my ($me, $args) = @_;
-
- return _not_yet();
-}
-
-sub _delete_post_id {
- my ($me, $args) = @_;
-
- return _not_yet();
-}
-
-sub _delete {
- my ($me, $id) =@_;
-
- return _not_yet();
-}
-
-sub _search {
- my ($me, $id) =@_;
-
- return _not_yet();
-}
-
-sub _not_yet {
- return 'まだ実装してないです';
-}
-
-sub said {
- my ($me, $args) = @_;
- my $resp_msg;
-
- if ($args->{body} =~ /$mu_re/) {
- $resp_msg = $me->_add($args) unless ($1 eq 'deb');
- } elsif ($args->{body} =~ /^ふみくん (.+)/) {
- my $cmd = $1;
- if ($cmd eq 'いまのなし') {
- $resp_msg = $me->_delete_prev($args);
- } elsif ($cmd =~ /削除 ([0-9]+)$/) {
- $resp_msg = $me->_delete($args, $1);
- } elsif ($cmd =~ /\?$/) {
- $resp_msg = $me->_search($args);
- } elsif ($cmd =~ /つぎ/) {
- $resp_msg = $me->_search_next($args);
- }
- }
-
- $me->_response($args, $resp_msg) if ($resp_msg);
-}
-
-package main;
-use strict;
-use utf8;
-
-use Config::Simple;
-use File::Path;
+use Data::Dumper;
my $config_name = $ARGV[0] || 'not_found';
-my %cfg;
-my $config_path = ('/etc/mubot4fb/', $ENV{HOME} . '/.mubot4fb/', $ENV{PWD} . '/mubot4fb_');
-foreach my $c ($config_path) {
- my $config = $c . $config_name . '.conf';
- Config::Simple->import_from($config, \%cfg) if (-e $config);
+my $cfg = {};
+my $config_path = ['/etc/mubot4fb/'.$config_name,
+ $ENV{HOME} . '/.mubot4fb/'. $config_name,
+ $ENV{PWD} . '/mubot4fb_' . $config_name];
+
+my $c = Config::Any->load_stems({stems => $config_path, use_ext => 1, flatten_to_hash => 1});
+foreach my $i (keys %$c) {
+ $cfg = Hash::Merge::Simple->merge($cfg, $c->{$i});
}
-die 'missing config file' unless (keys %cfg);
+die 'missing config file' unless (keys %$cfg);
die 'missing some config parameters should be defined (irc_server, fb_app_id, fb_app_secret, fb_access_code, fb_page_id fb_postback_url)'
- if (!defined $cfg{'irc_server'}
- || !defined $cfg{'fb_app_id'}
- || !defined $cfg{'fb_app_secret'}
- || !defined $cfg{'fb_access_code'}
- || !defined $cfg{'fb_page_id'}
- || !defined $cfg{'fb_postback_url'}
+ if (!defined $cfg->{'irc_server'}
+ || !defined $cfg->{'fb_app_id'}
+ || !defined $cfg->{'fb_app_secret'}
+ || !defined $cfg->{'fb_access_code'}
+ || !defined $cfg->{'fb_page_id'}
+ || !defined $cfg->{'fb_postback_url'}
+ || !defined $cfg->{'db_user'}
+ || !defined $cfg->{'db_pass'}
);
-
-$cfg{irc_port} ||= 6667;
-$cfg{irc_channels} ||= ['#mubot4fb'];
-$cfg{irc_nick} ||= 'mubot4fb';
-$cfg{irc_name}||= $cfg{irc_nick};
-$cfg{irc_charset} ||= 'utf-8';
-$cfg{database} ||= $ENV{HOME} . '/.mubot4fb/data/' . $config_name . '.sqlite';
-
-my $bot = Mubot4FB->new(server => $cfg{'irc_server'},
- port => $cfg{'irc_port'},
- channels => $cfg{'irc_channels'},
- nick => $cfg{'irc_nick'},
- username => $cfg{'irc_name'},
- name => $cfg{'irc_name'},
- charset => $cfg{'irc_charset'},
- cfg => \%cfg)->run();
+$cfg = Data::Recursive::Encode->decode('utf8', $cfg);
+
+$cfg->{irc_port} ||= 6667;
+$cfg->{irc_channels} ||= ['#mubot4fb'];
+$cfg->{irc_nick} ||= 'mubot4fb';
+$cfg->{irc_name}||= $cfg->{irc_nick};
+$cfg->{irc_charset} ||= 'utf8';
+$cfg->{database} ||= 'mubot4fb';
+$cfg->{debug} ||= 0;
+
+my $bot = Mubot4FB->new(server => $cfg->{'irc_server'},
+ port => $cfg->{'irc_port'},
+ channels => $cfg->{'irc_channels'},
+ nick => $cfg->{'irc_nick'},
+ username => $cfg->{'irc_name'},
+ name => $cfg->{'irc_name'},
+ charset => $cfg->{'irc_charset'},
+ cfg => $cfg)->run();
1;