ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/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

# User Rev Content
1 elmex 1.1 #!/usr/bin/perl
2     use strict;
3     use JSONConnection;
4 elmex 1.3 use JSON::Syck;
5 elmex 1.2 use POSIX qw(strftime);
6     use CursesChatMainwindow;
7 elmex 1.1
8 elmex 1.3 our $CFG;
9 elmex 1.4 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 elmex 1.3
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 elmex 1.2 my $c = AnyEvent->condvar;
42 elmex 1.1
43 elmex 1.2 #timer ();
44 elmex 1.1
45     $js =
46     JSONClientConnection->new (packet_cb => sub {
47     my ($js, $data) = @_;
48     require JSON::Syck;
49 elmex 1.3 if ($data->{type} eq 'message') {
50     my ($src_id) = ($data->{src});
51 elmex 1.4 $known_ids{$src_id}->{send_id} = $data->{to}->{id};
52     write_chatline ($src_id, $data->{from}->{id}, $data->{timestamp}, $data->{message});
53 elmex 1.2 }
54 elmex 1.4 printline (debug => [0, JSON::Syck::Dump ($data)]);
55 elmex 1.1 });
56    
57     $js->connect (localhost => 1236);
58    
59 elmex 1.2 CursesChatMainwindow::init;
60 elmex 1.1
61 elmex 1.3 printline (status => ['p0', 0, "Connected!"]);
62     printline (statusline => [20, "Welcome to the json enhanced chat framework!"]);
63 elmex 1.2
64 elmex 1.4 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 elmex 1.2 CursesChatMainwindow::register_input_cb (sub {
122 elmex 1.3 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 elmex 1.2 } else {
129 elmex 1.3 select_buffer ('status');
130     printline (statusline => [20, "[status]"]);
131 elmex 1.1 }
132 elmex 1.3 return;
133     }
134    
135 elmex 1.4 if ($input =~ m/^\/buffer\s*(\S+)/) {
136 elmex 1.3 select_buffer ("$1");
137     printline (statusline => [20, "[$1]"]);
138 elmex 1.4 } elsif ($input =~ m/^\/list_buffers/) {
139     printline (undef, [0, "buffers:"]);
140     for (list_buffers) {
141     printline (undef, [0, "- $_"]);
142     }
143 elmex 1.2 } elsif ($input =~ m/^\/colors/) {
144     CursesChatMainwindow::print_colors;
145     } else {
146 elmex 1.4 my $dest_id = "" . current_buffer ();
147     my $msg = {
148 elmex 1.3 type => 'message',
149 elmex 1.4 dest => $dest_id,
150 elmex 1.2 message => $input
151 elmex 1.4 };
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 elmex 1.1 }
156 elmex 1.2 });
157 elmex 1.1
158     $c->wait;
159    
160 elmex 1.2 CursesChatMainwindow::end;