ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Net-IRC3/samples/jsonclient
Revision: 1.4
Committed: Mon Dec 25 21:54:46 2006 UTC (19 years, 9 months ago) by elmex
Branch: MAIN
Changes since 1.3: +95 -22 lines
Log Message:
improved the json chat client: fixed scrolling a bit, implemented
completion and fixed other weird behaviour

File Contents

# Content
1 #!/usr/bin/perl
2 use strict;
3 use JSONConnection;
4 use JSON::Syck;
5 use POSIX qw(strftime);
6 use CursesChatMainwindow;
7
8 our $CFG;
9 our %known_ids;
10 our $js;
11 our %completion = map { $_ => 1 } qw{
12 /buffer /list_buffers /colors
13 };
14
15 my $d = 0;
16 my $wt;
17 sub timer {
18 $wt = AnyEvent->timer (after => 3, cb => sub {
19 printline (status => [0, "TEST $d"]); $d++;
20 timer ();
21 });
22 }
23
24 sub write_chatline {
25 my ($buffer, $nick, $time, $msg) = @_;
26 my $ts = POSIX::strftime ("%T", localtime ($time));
27 $ts = "[$ts] $nick> ";
28 my (@chatline) = (("p".length $ts), 0, "$ts$msg");
29 printline ($buffer, \@chatline);
30 }
31
32 sub load_cfg {
33 $CFG ||= {};
34 return unless -e "$ENV{HOME}/.jsonircclrc";
35 open CFGH, "<", "$ENV{HOME}/.jsonircclrc" or die "Couldn't open ~/.jsonircclrc: $!";
36 $::CFG = JSON::Syck::Load (do { local $/; <CFGH> });
37 }
38
39 load_cfg ();
40
41 my $c = AnyEvent->condvar;
42
43 #timer ();
44
45 $js =
46 JSONClientConnection->new (packet_cb => sub {
47 my ($js, $data) = @_;
48 require JSON::Syck;
49 if ($data->{type} eq 'message') {
50 my ($src_id) = ($data->{src});
51 $known_ids{$src_id}->{send_id} = $data->{to}->{id};
52 write_chatline ($src_id, $data->{from}->{id}, $data->{timestamp}, $data->{message});
53 }
54 printline (debug => [0, JSON::Syck::Dump ($data)]);
55 });
56
57 $js->connect (localhost => 1236);
58
59 CursesChatMainwindow::init;
60
61 printline (status => ['p0', 0, "Connected!"]);
62 printline (statusline => [20, "Welcome to the json enhanced chat framework!"]);
63
64 sub find_common_prefix {
65 my (@words) = @_;
66 @words = sort { length ($a) <=> length ($b) } @words;
67 my $shortest = $words[0];
68
69 while ($shortest ne '') {
70 my $no_match = 0;
71 for (@words) {
72 unless (/^\Q$shortest\E/) {
73 $no_match = 1;
74 last;
75 }
76 }
77
78 return $shortest if not $no_match;
79 substr $shortest, -1, 1, '';
80 }
81
82 return '';
83 }
84
85 CursesChatMainwindow::register_complete_cb (sub {
86 my ($word, $first_compl, $idx, @line) = @_;
87
88 # TODO: make completion cycling with $first_compl
89 # printline (undef, [0, "f[$first_compl]"]);
90
91 my @found;
92 if ($idx == 0) {
93 for (keys %completion) {
94 if (/^\Q$word\E/) {
95 push @found, $_;
96 }
97 }
98 } else {
99 my %buffers = map { $_ => 1 } list_buffers;
100 for (keys %known_ids) {
101 delete $buffers{$_};
102 if (/^\Q$word\E/) {
103 push @found, $_;
104 }
105 }
106 for (keys %buffers) {
107 if (/^\Q$word\E/) {
108 push @found, $_;
109 }
110 }
111 }
112 return "$found[0] " if @found == 1;
113 if (@found) {
114 printline (undef, [0, "$word: " . join ", ", @found]);
115 return find_common_prefix (@found);
116 }
117
118 return $word;
119 });
120
121 CursesChatMainwindow::register_input_cb (sub {
122 my ($input, $escape) = @_;
123
124 unless (defined $input) {
125 if (exists $CFG->{buffers}->{$escape}) {
126 select_buffer (my $buf = $CFG->{buffers}->{$escape} || 'status');
127 printline (statusline => [20, "[$buf]"]);
128 } else {
129 select_buffer ('status');
130 printline (statusline => [20, "[status]"]);
131 }
132 return;
133 }
134
135 if ($input =~ m/^\/buffer\s*(\S+)/) {
136 select_buffer ("$1");
137 printline (statusline => [20, "[$1]"]);
138 } elsif ($input =~ m/^\/list_buffers/) {
139 printline (undef, [0, "buffers:"]);
140 for (list_buffers) {
141 printline (undef, [0, "- $_"]);
142 }
143 } elsif ($input =~ m/^\/colors/) {
144 CursesChatMainwindow::print_colors;
145 } else {
146 my $dest_id = "" . current_buffer ();
147 my $msg = {
148 type => 'message',
149 dest => $dest_id,
150 message => $input
151 };
152 $js->send_data ($msg);
153 printline (debug => [0, JSON::Syck::Dump ($msg)]);
154 write_chatline ($dest_id, $known_ids{$dest_id}->{send_id} || "", time, $input);
155 }
156 });
157
158 $c->wait;
159
160 CursesChatMainwindow::end;