| 1 | use warnings; |
|---|
| 2 | use strict; |
|---|
| 3 | |
|---|
| 4 | =head1 NAME |
|---|
| 5 | |
|---|
| 6 | BarnOwl::Module::AIM |
|---|
| 7 | |
|---|
| 8 | =head1 DESCRIPTION |
|---|
| 9 | |
|---|
| 10 | BarnOwl module implementing AIM support via Net::OSCAR |
|---|
| 11 | |
|---|
| 12 | =cut |
|---|
| 13 | |
|---|
| 14 | package BarnOwl::Module::AIM; |
|---|
| 15 | |
|---|
| 16 | use Net::OSCAR; |
|---|
| 17 | |
|---|
| 18 | our @oscars; |
|---|
| 19 | |
|---|
| 20 | sub on_im_in { |
|---|
| 21 | my ($oscar, $sender, $message, $is_away) = @_; |
|---|
| 22 | my $msg = BarnOwl::Message->new( |
|---|
| 23 | type => 'AIM', |
|---|
| 24 | direction => 'in', |
|---|
| 25 | sender => $sender, |
|---|
| 26 | origbody => $message, |
|---|
| 27 | away => $is_away, |
|---|
| 28 | body => zformat($message, $is_away), |
|---|
| 29 | recipient => get_screenname($oscar), |
|---|
| 30 | replycmd => |
|---|
| 31 | "aimwrite -a '" . get_screenname($oscar) . "' $sender", |
|---|
| 32 | replysendercmd => |
|---|
| 33 | "aimwrite -a '" . get_screenname($oscar) . "' $sender", |
|---|
| 34 | ); |
|---|
| 35 | BarnOwl::queue_message($msg); |
|---|
| 36 | } |
|---|
| 37 | |
|---|
| 38 | sub cmd_aimlogin { |
|---|
| 39 | my ($cmd, $user, $pass) = @_; |
|---|
| 40 | if (!defined $user) { |
|---|
| 41 | BarnOwl::start_question('Username: ', sub { |
|---|
| 42 | cmd_aimlogin($cmd, @_); |
|---|
| 43 | }); |
|---|
| 44 | } elsif (!defined $pass) { |
|---|
| 45 | BarnOwl::start_password('Password: ', sub { |
|---|
| 46 | cmd_aimlogin($cmd, $user, @_); |
|---|
| 47 | }); |
|---|
| 48 | } else { |
|---|
| 49 | my $oscar = Net::OSCAR->new(); |
|---|
| 50 | $oscar->set_callback_im_in(\&on_im_in); |
|---|
| 51 | $oscar->set_callback_signon_done(sub ($) { |
|---|
| 52 | BarnOwl::admin_message('AIM', |
|---|
| 53 | 'Logged in to AIM as ' . shift->screenname); |
|---|
| 54 | }); |
|---|
| 55 | $oscar->signon( |
|---|
| 56 | screenname => $user, |
|---|
| 57 | password => $pass |
|---|
| 58 | ); |
|---|
| 59 | push @oscars, $oscar; |
|---|
| 60 | } |
|---|
| 61 | } |
|---|
| 62 | |
|---|
| 63 | sub cmd_aimwrite { |
|---|
| 64 | my ($cmd, $recipient) = @_; |
|---|
| 65 | BarnOwl::start_edit_win(join(' ', @_), sub { |
|---|
| 66 | my ($body) = @_; |
|---|
| 67 | my $oscar = get_oscar(); |
|---|
| 68 | my $sender = get_screenname($oscar); |
|---|
| 69 | $oscar->send_im($recipient, $body); |
|---|
| 70 | BarnOwl::queue_message(BarnOwl::Message->new( |
|---|
| 71 | type => 'AIM', |
|---|
| 72 | direction => 'in', |
|---|
| 73 | sender => $sender, |
|---|
| 74 | origbody => $body, |
|---|
| 75 | away => 0, |
|---|
| 76 | body => zformat($body, 0), |
|---|
| 77 | recipient => $recipient, |
|---|
| 78 | replycmd => |
|---|
| 79 | "aimwrite -a '" . get_screenname($oscar) . "' $sender", |
|---|
| 80 | replysendercmd => |
|---|
| 81 | "aimwrite -a '" . get_screenname($oscar) . "' $sender", |
|---|
| 82 | )); |
|---|
| 83 | }); |
|---|
| 84 | } |
|---|
| 85 | |
|---|
| 86 | BarnOwl::new_command(aimlogin => \&cmd_aimlogin, {}); |
|---|
| 87 | BarnOwl::new_command(aimwrite => \&cmd_aimwrite, {}); |
|---|
| 88 | |
|---|
| 89 | sub main_loop() { |
|---|
| 90 | for my $oscar (@oscars) { |
|---|
| 91 | $oscar->do_one_loop(); |
|---|
| 92 | } |
|---|
| 93 | } |
|---|
| 94 | $BarnOwl::Hooks::mainLoop->add(\&main_loop); |
|---|
| 95 | |
|---|
| 96 | ### helpers ### |
|---|
| 97 | |
|---|
| 98 | sub zformat($$) { |
|---|
| 99 | # TODO subclass HTML::Parser |
|---|
| 100 | my ($message, $is_away) = @_; |
|---|
| 101 | if ($is_away) { |
|---|
| 102 | return BarnOwl::boldify('[away]') . " $message"; |
|---|
| 103 | } else { |
|---|
| 104 | return $message; |
|---|
| 105 | } |
|---|
| 106 | } |
|---|
| 107 | |
|---|
| 108 | sub get_oscar() { |
|---|
| 109 | if (scalar @oscars == 0) { |
|---|
| 110 | die "You are not logged in to AIM." |
|---|
| 111 | } elsif (scalar @oscars == 1) { |
|---|
| 112 | return $oscars[0]; |
|---|
| 113 | } else { |
|---|
| 114 | my $m = BarnOwl::getcurmsg(); |
|---|
| 115 | if ($m && $m->type eq 'AIM') { |
|---|
| 116 | for my $oscar (@oscars) { |
|---|
| 117 | return $oscar if ($oscar->screenname eq $m->recipient); |
|---|
| 118 | } |
|---|
| 119 | } |
|---|
| 120 | } |
|---|
| 121 | die('You must specify an account with -a'); |
|---|
| 122 | } |
|---|
| 123 | |
|---|
| 124 | sub get_screenname($) { |
|---|
| 125 | # TODO qualify realm |
|---|
| 126 | return shift->screenname; |
|---|
| 127 | } |
|---|
| 128 | |
|---|
| 129 | 1; |
|---|
| 130 | |
|---|
| 131 | # vim: set sw=4 et cin: |
|---|