[280] in BarnOwl Developers
[D-O-H] r440 - / trunk/owl trunk/owl/perl trunk/owl/perl/modules
daemon@ATHENA.MIT.EDU (hartmans@MIT.EDU)
Thu Oct 29 18:04:27 2009
Resent-From: nelhage@mit.edu
Resent-To: barnowl-dev-mtg@charon.mit.edu
To: dirty-owl-hackers@mit.edu
From: hartmans@MIT.EDU
Reply-To: dirty-owl-hackers@MIT.EDU
Date: Wed, 1 Nov 2006 01:00:04 -0500 (EST)
Author: hartmans
Date: 2006-11-01 01:00:02 -0500 (Wed, 01 Nov 2006)
New Revision: 440
Added:
trunk/owl/perl/
trunk/owl/perl/lib/
trunk/owl/perl/modules/
trunk/owl/perl/modules/jabber.pl
Modified:
/
Log:
r1344@luminous: hartmans | 2006-10-31 23:58:36 -0500
jabber.pl is a core module
Property changes on:
___________________________________________________________________
Name: svk:merge
- 6aa88b72-b502-0410-8cb4-a5dd0230fb79:/owl-local:1343
+ 6aa88b72-b502-0410-8cb4-a5dd0230fb79:/owl-local:1344
Copied: trunk/owl/perl/modules/jabber.pl (from rev 437, trunk/conf.asedeno/owl/modules/jabber.pl)
===================================================================
--- trunk/owl/perl/modules/jabber.pl (rev 0)
+++ trunk/owl/perl/modules/jabber.pl 2006-11-01 06:00:02 UTC (rev 440)
@@ -0,0 +1,388 @@
+package owl_jabber;
+use Authen::SASL qw(Perl);
+use Net::Jabber;
+################################################################################
+# owl perl jabber support
+#
+# Todo:
+# Connect command.
+#
+################################################################################
+
+our $client;
+our $jid;
+
+sub onStart
+{
+ if(eval{\&owl::queue_message})
+ {
+ register_owl_commands();
+ }
+ else
+ {
+ # Our owl doesn't support queue_message. Unfortunately, this
+ # means it probably *also* doesn't support owl::error. So just
+ # give up silently.
+ }
+}
+push @::onStartSubs, \&onStart;
+
+sub onMainLoop
+{
+ return if ($client == undef);
+
+ my $status = $client->Process(0);
+ if ($status == 0 # No data received
+ || $status == 1) # Data received
+ {
+ }
+ else #Error
+ {
+ queue_admin_msg("Jabber disconnected.");
+ $client = undef;
+ return;
+ }
+
+ if ($::shutdown)
+ {
+ $client->Disconnect();
+ $client = undef;
+ return;
+ }
+}
+push @::onMainLoop, \&onMainLoop;
+
+################################################################################
+### Owl Commands
+sub register_owl_commands()
+{
+ owl::new_command(
+ jabberlogin => \&cmd_login,
+ { summary => "Log into jabber", }
+ );
+ owl::new_command(
+ jabberlogout => \&cmd_logout,
+ { summary => "Log out of jabber" }
+ );
+ owl::new_command(
+ jwrite => \&cmd_jwrite,
+ {
+ summary => "Send a Jabber Message",
+ usage => "jwrite JID [-t thread]"
+ }
+ );
+ owl::new_command(
+ jchat => \&cmd_jwrite_gc,
+ {
+ summary => "Send a Jabber Message",
+ usage => "jchat [room]@[server]"
+ }
+ );
+ owl::new_command(
+ jjoin => \&cmd_join_gc,
+ {
+ summary => "Joins a jabber groupchat.",
+ usage => "jjoin [room]@[server]/[nick]"
+ }
+ );
+ owl::new_command(
+ jpart => \&cmd_part_gc,
+ {
+ summary => "Parts a jabber groupchat.",
+ usage => "jpart [room]@[server]/[nick]"
+ }
+ );
+}
+
+sub cmd_login
+{
+ if ($client != undef)
+ {
+ queue_admin_msg("Already logged in.");
+ return;
+ }
+
+ # These strings should not be hard-coded here.
+ $client = Net::Jabber::Client->new();
+ $client->SetMessageCallBacks(chat => sub { owl_jabber::process_incoming_chat_message(@_) },
+ error => sub { owl_jabber::process_incoming_error_message(@_) },
+ groupchat => sub { owl_jabber::process_incoming_groupchat_message(@_) },
+ headline => sub { owl_jabber::process_incoming_headline_message(@_) },
+ normal => sub { owl_jabber::process_incoming_normal_message(@_) });
+ my $status = $client->Connect(hostname => 'jabber.mit.edu',
+ tls => 1,
+ port => 5222,
+ componentname => 'mit.edu');
+
+ if (!$status)
+ {
+ owl::error("We failed to connect");
+ return;
+ }
+
+ my @result = $client->AuthSend(username => $ENV{USER}, resource => 'owl', password => '');
+ if($result[0] ne 'ok') {
+ owl::error("Error in connect: " . join(" ", $result[1..$#result]));
+ $client->Disconnect();
+ $client = undef;
+ return;
+ }
+
+ $jid = new Net::Jabber::JID;
+ $jid->SetJID(userid => $ENV{USER},
+ server => ($client->{SERVER}->{componentname} ||
+ $client->{SERVER}->{hostname}),
+ resource => 'owl');
+
+ $client->PresenceSend(priority => 1);
+ queue_admin_msg("Connected to jabber as ".$jid->GetJID('full'));
+
+ return "";
+}
+
+sub cmd_logout
+{
+ if ($client)
+ {
+ $client->Disconnect();
+ $client = undef;
+ queue_admin_msg("Jabber disconnected.");
+ }
+ return "";
+}
+
+our $jwrite_to;
+our $jwrite_thread;
+our $jwrite_subject;
+our $jwrite_type;
+sub cmd_jwrite
+{
+ if (!$client)
+ {
+ # Error here
+ return;
+ }
+
+ $jwrite_to = "";
+ $jwrite_thread = "";
+ $jwrite_subject = "";
+ $jwrite_type = "chat";
+ my @args = @_;
+ my $argsLen = @args;
+
+ JW_ARG: for (my $i = 1; $i < $argsLen; $i++)
+ {
+ $args[$i] =~ /^-t$/ && ($jwrite_thread = $args[++$i] && next JW_ARG);
+ $args[$i] =~ /^-s$/ && ($jwrite_subject = $args[++$i] && next JW_ARG);
+ if ($jwrite_to ne '')
+ {
+ # Too many To's
+ $jwrite_to = '';
+ last;
+ }
+ if ($jwrite_to)
+ {
+ $jwrite_to == '';
+ last;
+ }
+ $jwrite_to = $args[$i];
+ }
+
+ if(!$jwrite_to) {
+ owl::error("Usage: jwrite JID [-t thread] [-s 'subject']");
+ return;
+ }
+
+ owl::message("Type your message below. End with a dot on a line by itself. ^C will quit.");
+ owl::start_edit_win(join(' ', @args), \&process_owl_jwrite);
+}
+
+sub cmd_join_gc
+{
+ if (!$client)
+ {
+ # Error here
+ return;
+ }
+ if(!$_[1])
+ {
+ owl::error("Usage: jchat [room]@[server]/[nick]");
+ return;
+ }
+
+ my $x = new XML::Stream::Node('x');
+ $x->put_attrib(xmlns => 'http://jabber.org/protocol/muc');
+ $x->add_child('history')->put_attrib(maxchars => '0');
+
+
+ my $presence = new Net::Jabber::Presence;
+ $presence->SetPresence(to => $_[1]);
+ $presence->AddX($x);
+
+ $client->Send($presence);
+ return "";
+}
+
+sub cmd_part_gc
+{
+ if (!$client)
+ {
+ # Error here
+ return;
+ }
+ if(!$_[1])
+ {
+ owl::error("Usage: jchat [room]@[server]/[nick]");
+ return;
+ }
+
+ $client->PresenceSend(to=>$_[1], type=>'unavailable');
+ return "";
+}
+
+sub cmd_jwrite_gc
+{
+ if (!$client)
+ {
+ # Error here
+ return;
+ }
+
+ $jwrite_to = $_[1];
+ $jwrite_thread = "";
+ $jwrite_subject = "";
+ $jwrite_type = "groupchat";
+ my @args = @_;
+ my $argsLen = @args;
+
+ owl::message("Type your message below. End with a dot on a line by itself. ^C will quit.");
+ owl::start_edit_win(join(' ', @args), \&process_owl_jwrite);
+}
+
+################################################################################
+### Owl Callbacks
+sub process_owl_jwrite
+{
+ my $body = shift;
+
+ my $j = new Net::XMPP::Message;
+ $body =~ s/\n\z//;
+ $j->SetMessage(to => $jwrite_to,
+ from => $jid->GetJID('full'),
+ type => $jwrite_type,
+ body => $body
+ );
+ $j->SetThread($jwrite_thread) if ($jwrite_thread);
+ $j->SetSubject($jwrite_subject) if ($jwrite_subject);
+
+ my $m = j2o($j, 'out');
+ if ($jwrite_type ne 'groupchat')
+ {
+ #XXX TODO: Check for displayoutgoing.
+ owl::queue_message($m);
+ }
+ $client->Send($j);
+}
+
+### XMPP Callbacks
+
+sub process_incoming_chat_message
+{
+ my ($session, $j) = @_;
+ owl::queue_message(j2o($j, 'in'));
+}
+
+sub process_incoming_error_message
+{
+ my ($session, $j) = @_;
+ queue_admin_msg("Error ".$j->GetErrorCode()." sending to ".$j->GetFrom('jid')->GetJID('base'));
+}
+
+sub process_incoming_groupchat_message
+{
+ my ($session, $j) = @_;
+ # HACK IN PROGRESS (ignoring delayed messages)
+ return if ($j->DefinedX('jabber:x:delay') && $j->GetX('jabber:x:delay'));
+ owl::queue_message(j2o($j, 'in'));
+}
+
+sub process_incoming_headline_message
+{
+ my ($session, $j) = @_;
+ owl::queue_message(j2o($j, 'in'));
+}
+
+sub process_incoming_normal_message
+{
+ my ($session, $j) = @_;
+ owl::queue_message(j2o($j, 'in'));
+}
+
+
+### Helper functions
+
+sub j2o
+{
+ my $j = shift;
+ my $dir = shift;
+
+ my %props = (type => 'jabber',
+ direction => $dir);
+
+
+ $props{replycmd} = "jwrite";
+
+ $props{jtype} = $j->GetType();
+ $props{jtype} =~ /^(?:headline|error)$/ && {$props{replycmd} = undef};
+ $props{jtype} =~ /^groupchat$/ && {$props{replycmd} = "jchat"};
+
+ $props{isprivate} = $props{jtype} =~ /^(?:normal|chat)$/;
+
+ my $reply_to;
+ if ($j->DefinedTo())
+ {
+ my $jid = $j->GetTo('jid');
+ $props{recipient} = $jid->GetJID('base');
+ $props{to_jid} = $jid->GetJID('full');
+ if ($dir eq 'out')
+ {
+ $reply_to = $props{to_jid};
+ $props{jtype} =~ /^groupchat$/ && {$reply_to = $jid->GetJID('base')};
+ }
+ }
+ if ($j->DefinedFrom())
+ {
+ my $jid = $j->GetFrom('jid');
+ $props{sender} = $jid->GetJID('base');
+ $props{from_jid} = $jid->GetJID('full');
+ $reply_to = $props{from_jid} if ($dir eq 'in');
+ if ($dir eq 'in')
+ {
+ $reply_to = $props{from_jid};
+ $props{jtype} =~ /^groupchat$/ && {$reply_to = $jid->GetJID('base')};
+ }
+ }
+
+ $props{subject} = $j->GetSubject() if ($j->DefinedSubject());
+ $props{body} = $j->GetBody() if ($j->DefinedBody());
+# if ($j->DefinedThread())
+# {
+# $props{thread} = $j->GetThread() if ($j->DefinedThread());
+# $props{replycmd} .= " -t $props{thread}";
+# }
+ $props{error} = $j->GetError() if ($j->DefinedError());
+ $props{error_code} = $j->GetErrorCode() if ($j->DefinedErrorCode());
+ $props{replycmd} .= " $reply_to";
+ $props{replysendercmd} = $props{replycmd};
+
+ return owl::Message->new(%props);
+}
+
+sub queue_admin_msg
+{
+ my $err = shift;
+ my $m = owl::Message->new(type => 'admin',
+ direction => 'none',
+ body => $err);
+ owl::queue_message($m);
+}