lijab 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/lijab +9 -0
- data/ext/extconf.rb +20 -0
- data/ext/readline_extra.c +172 -0
- data/ext/test.rb +29 -0
- data/lib/bleh.rb +45 -0
- data/lib/configs/commands/cowsay.rb +33 -0
- data/lib/configs/hooks/ting.rb +23 -0
- data/lib/lijab.rb +7 -0
- data/lib/lijab/commands.rb +139 -0
- data/lib/lijab/commands/contacts.rb +101 -0
- data/lib/lijab/commands/options.rb +49 -0
- data/lib/lijab/commands/simple.rb +132 -0
- data/lib/lijab/commands/status.rb +63 -0
- data/lib/lijab/commands/subscription.rb +78 -0
- data/lib/lijab/config.rb +174 -0
- data/lib/lijab/contacts.rb +324 -0
- data/lib/lijab/history.rb +122 -0
- data/lib/lijab/hooks.rb +109 -0
- data/lib/lijab/input.rb +234 -0
- data/lib/lijab/main.rb +248 -0
- data/lib/lijab/out.rb +174 -0
- data/lib/lijab/term/ansi.rb +20 -0
- data/lib/lijab/version.rb +4 -0
- data/lib/lijab/xmpp4r/message.rb +45 -0
- data/lib/readline/extra.rb +7 -0
- metadata +122 -0
data/bin/lijab
ADDED
data/ext/extconf.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# Loads mkmf which is used to make makefiles for Ruby extensions
|
2
|
+
require 'mkmf'
|
3
|
+
|
4
|
+
dir_config("readline")
|
5
|
+
|
6
|
+
$headers = ["stdio.h", "readline/readline.h"]
|
7
|
+
|
8
|
+
exit unless have_library("readline", "readline")
|
9
|
+
|
10
|
+
$headers.each { |h| exit unless have_header(h) }
|
11
|
+
|
12
|
+
%w{"rl_line_buffer"
|
13
|
+
"rl_insert_text"
|
14
|
+
"rl_parse_and_bind"
|
15
|
+
"rl_redisplay"}.each { |f| exit unless have_func(f, $headers) }
|
16
|
+
|
17
|
+
%w{"rl_pre_input_hook"
|
18
|
+
"rl_getc_function"}.each { |f| exit unless have_var(f, $headers) }
|
19
|
+
|
20
|
+
create_makefile("readline_extra")
|
@@ -0,0 +1,172 @@
|
|
1
|
+
|
2
|
+
#include <stdio.h>
|
3
|
+
|
4
|
+
#include <readline/readline.h>
|
5
|
+
|
6
|
+
#include "ruby.h"
|
7
|
+
#include "rubyio.h"
|
8
|
+
|
9
|
+
#define PRE_INPUT_PROC "pre_input_proc"
|
10
|
+
static ID pre_input_proc;
|
11
|
+
|
12
|
+
#define CHAR_INPUT_PROC "char_input_proc"
|
13
|
+
static ID char_input_proc;
|
14
|
+
|
15
|
+
|
16
|
+
VALUE mReadlineExtra = Qnil;
|
17
|
+
|
18
|
+
void Init_readline_extra();
|
19
|
+
|
20
|
+
static VALUE readline_extra_s_get_line_buffer(VALUE self);
|
21
|
+
static VALUE readline_extra_s_set_line_buffer(VALUE self, VALUE str);
|
22
|
+
static VALUE readline_extra_insert_text(VALUE self, VALUE text);
|
23
|
+
static VALUE readline_extra_parse_and_bind(VALUE self, VALUE text);
|
24
|
+
static VALUE readline_extra_redisplay(VALUE self);
|
25
|
+
|
26
|
+
static VALUE readline_extra_s_set_pre_input_proc(VALUE self, VALUE proc);
|
27
|
+
static VALUE readline_extra_s_get_pre_input_proc(VALUE self);
|
28
|
+
static int readline_extra_on_pre_input_hook(void);
|
29
|
+
|
30
|
+
int readline_extra_getc(FILE *stream);
|
31
|
+
static VALUE readline_extra_s_set_char_input_proc(VALUE self, VALUE proc);
|
32
|
+
static VALUE readline_extra_s_get_char_input_proc(VALUE self);
|
33
|
+
static int readline_extra_on_char_input_hook(int c);
|
34
|
+
|
35
|
+
void Init_readline_extra()
|
36
|
+
{
|
37
|
+
mReadlineExtra = rb_define_module("Readline");
|
38
|
+
|
39
|
+
pre_input_proc = rb_intern(PRE_INPUT_PROC);
|
40
|
+
rl_pre_input_hook = readline_extra_on_pre_input_hook;
|
41
|
+
|
42
|
+
rb_define_singleton_method(mReadlineExtra, "pre_input_proc=", readline_extra_s_set_pre_input_proc, 1);
|
43
|
+
rb_define_singleton_method(mReadlineExtra, "pre_input_proc", readline_extra_s_get_pre_input_proc, 0);
|
44
|
+
|
45
|
+
rl_getc_function = readline_extra_getc;
|
46
|
+
char_input_proc = rb_intern(CHAR_INPUT_PROC);
|
47
|
+
|
48
|
+
rb_define_singleton_method(mReadlineExtra, "char_input_proc=", readline_extra_s_set_char_input_proc, 1);
|
49
|
+
rb_define_singleton_method(mReadlineExtra, "char_input_proc", readline_extra_s_get_char_input_proc, 0);
|
50
|
+
|
51
|
+
rb_define_module_function(mReadlineExtra, "line_buffer", readline_extra_s_get_line_buffer, 0);
|
52
|
+
rb_define_module_function(mReadlineExtra, "line_buffer=", readline_extra_s_set_line_buffer, 1);
|
53
|
+
rb_define_module_function(mReadlineExtra, "insert_text", readline_extra_insert_text, 1);
|
54
|
+
rb_define_module_function(mReadlineExtra, "parse_and_bind", readline_extra_parse_and_bind, 1);
|
55
|
+
rb_define_module_function(mReadlineExtra, "redisplay", readline_extra_redisplay, 0);
|
56
|
+
|
57
|
+
}
|
58
|
+
|
59
|
+
static VALUE readline_extra_s_get_line_buffer(VALUE self)
|
60
|
+
{
|
61
|
+
if (rl_line_buffer)
|
62
|
+
return rb_tainted_str_new2(rl_line_buffer);
|
63
|
+
else
|
64
|
+
return rb_tainted_str_new2("");
|
65
|
+
}
|
66
|
+
|
67
|
+
static VALUE readline_extra_s_set_line_buffer(VALUE self, VALUE str)
|
68
|
+
{
|
69
|
+
rl_replace_line(RSTRING(str)->ptr, 1);
|
70
|
+
rl_point = rl_end;
|
71
|
+
|
72
|
+
return readline_extra_s_get_line_buffer(self);
|
73
|
+
}
|
74
|
+
|
75
|
+
static VALUE readline_extra_insert_text(VALUE self, VALUE text)
|
76
|
+
{
|
77
|
+
rl_insert_text(RSTRING(text)->ptr);
|
78
|
+
return self;
|
79
|
+
}
|
80
|
+
|
81
|
+
// doesn't seem to work
|
82
|
+
static VALUE readline_extra_parse_and_bind(VALUE self, VALUE text)
|
83
|
+
{
|
84
|
+
rl_parse_and_bind(RSTRING(text)->ptr);
|
85
|
+
return self;
|
86
|
+
}
|
87
|
+
|
88
|
+
static VALUE readline_extra_redisplay(VALUE self)
|
89
|
+
{
|
90
|
+
rl_redisplay();
|
91
|
+
return self;
|
92
|
+
}
|
93
|
+
|
94
|
+
static int
|
95
|
+
readline_extra_on_pre_input_hook(void)
|
96
|
+
{
|
97
|
+
VALUE proc;
|
98
|
+
|
99
|
+
proc = rb_attr_get(mReadlineExtra, pre_input_proc);
|
100
|
+
|
101
|
+
if (NIL_P(proc))
|
102
|
+
return -1;
|
103
|
+
|
104
|
+
rb_funcall(proc, rb_intern("call"), 0);
|
105
|
+
|
106
|
+
return 0;
|
107
|
+
}
|
108
|
+
|
109
|
+
static VALUE
|
110
|
+
readline_extra_s_set_pre_input_proc(VALUE self, VALUE proc)
|
111
|
+
{
|
112
|
+
rb_secure(4);
|
113
|
+
|
114
|
+
if (!NIL_P(proc) && !rb_respond_to(proc, rb_intern("call")))
|
115
|
+
rb_raise(rb_eArgError, "argument must respond to `call'");
|
116
|
+
|
117
|
+
return rb_ivar_set(mReadlineExtra, pre_input_proc, proc);
|
118
|
+
}
|
119
|
+
|
120
|
+
static VALUE
|
121
|
+
readline_extra_s_get_pre_input_proc(VALUE self)
|
122
|
+
{
|
123
|
+
rb_secure(4);
|
124
|
+
return rb_attr_get(mReadlineExtra, pre_input_proc);
|
125
|
+
}
|
126
|
+
|
127
|
+
int readline_extra_getc(FILE *stream)
|
128
|
+
{
|
129
|
+
int c;
|
130
|
+
c = rl_getc(stream);
|
131
|
+
return readline_extra_on_char_input_hook(c);
|
132
|
+
}
|
133
|
+
|
134
|
+
static int
|
135
|
+
readline_extra_on_char_input_hook(int c)
|
136
|
+
{
|
137
|
+
VALUE proc, ret;
|
138
|
+
|
139
|
+
proc = rb_attr_get(mReadlineExtra, char_input_proc);
|
140
|
+
|
141
|
+
if (NIL_P(proc))
|
142
|
+
return c;
|
143
|
+
|
144
|
+
ret = rb_funcall(proc, rb_intern("call"), 1, INT2FIX(c));
|
145
|
+
|
146
|
+
if(ret == Qnil)
|
147
|
+
return 0;
|
148
|
+
|
149
|
+
if(!FIXNUM_P(ret))
|
150
|
+
rb_raise(rb_eTypeError, "Readline::char_input_proc must return nil or a Fixnum");
|
151
|
+
|
152
|
+
return (int)FIX2INT(ret);
|
153
|
+
}
|
154
|
+
|
155
|
+
static VALUE
|
156
|
+
readline_extra_s_set_char_input_proc(VALUE self, VALUE proc)
|
157
|
+
{
|
158
|
+
rb_secure(4);
|
159
|
+
|
160
|
+
if (!NIL_P(proc) && !rb_respond_to(proc, rb_intern("call")))
|
161
|
+
rb_raise(rb_eArgError, "argument must respond to `call'");
|
162
|
+
|
163
|
+
return rb_ivar_set(mReadlineExtra, char_input_proc, proc);
|
164
|
+
}
|
165
|
+
|
166
|
+
static VALUE
|
167
|
+
readline_extra_s_get_char_input_proc(VALUE self)
|
168
|
+
{
|
169
|
+
rb_secure(4);
|
170
|
+
return rb_attr_get(mReadlineExtra, char_input_proc);
|
171
|
+
}
|
172
|
+
|
data/ext/test.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'readline'
|
2
|
+
require 'readline_extra'
|
3
|
+
|
4
|
+
Thread.abort_on_exception = true
|
5
|
+
Thread.new do
|
6
|
+
sleep(40)
|
7
|
+
#puts
|
8
|
+
#puts "got #{Readline::line_buffer}"
|
9
|
+
#print "reset to: "
|
10
|
+
#p (Readline::line_buffer = "congaland!")
|
11
|
+
##puts "\n#{Readline::line_buffer}\n> "
|
12
|
+
#Readline::line_buffer = "congaland!"
|
13
|
+
Readline::line_buffer = ""
|
14
|
+
puts
|
15
|
+
#print "> #{Readline::line_buffer}"
|
16
|
+
#$stdout.flush
|
17
|
+
Readline::redisplay
|
18
|
+
end
|
19
|
+
|
20
|
+
trap('SIGINT') do
|
21
|
+
Readline::line_buffer = ""
|
22
|
+
print "\n> "
|
23
|
+
$stdout.flush
|
24
|
+
#print "> #{Readline::line_buffer}"
|
25
|
+
#$stdout.flush
|
26
|
+
Readline::redisplay
|
27
|
+
end
|
28
|
+
|
29
|
+
puts Readline::readline('> ')
|
data/lib/bleh.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'xmpp4r'
|
3
|
+
require 'xmpp4r/client'
|
4
|
+
require 'xmpp4r/roster'
|
5
|
+
require 'xmpp4r/vcard'
|
6
|
+
include Jabber
|
7
|
+
|
8
|
+
Thread.abort_on_exception = true
|
9
|
+
Jabber::debug = true if ARGV.length > 0
|
10
|
+
$jid = JID.new("a@poobar/bloh")
|
11
|
+
$cl = Client.new($jid)
|
12
|
+
$cl.connect("localhost")
|
13
|
+
$cl.auth("lalala")
|
14
|
+
#$jid = JID.new("pflouret@gmail.com/irb")
|
15
|
+
#$cl = Client.new($jid)
|
16
|
+
#$cl.connect("talk.google.com")
|
17
|
+
#$cl.auth("")
|
18
|
+
$roster = Roster::Helper.new($cl)
|
19
|
+
self_ri = Roster::Helper::RosterItem.new($cl)
|
20
|
+
self_ri.jid = $jid
|
21
|
+
$roster.items[self_ri.jid] = self_ri
|
22
|
+
$roster.wait_for_roster
|
23
|
+
$v = Vcard::Helper.new($cl)
|
24
|
+
|
25
|
+
require 'pp'
|
26
|
+
def prin(from, i, pr)
|
27
|
+
puts
|
28
|
+
puts from
|
29
|
+
p i
|
30
|
+
puts pr.from
|
31
|
+
p pr.type
|
32
|
+
p pr.show
|
33
|
+
p pr.status
|
34
|
+
p pr.priority
|
35
|
+
#puts
|
36
|
+
#pp $roster.items
|
37
|
+
end
|
38
|
+
|
39
|
+
$roster.add_subscription_callback { |i, pr| prin(:subscallback, i, pr) }
|
40
|
+
$roster.add_subscription_request_callback { |i, pr| prin(:reqcallback, i, pr) }
|
41
|
+
|
42
|
+
$cl.send(Jabber::Presence.new.set_type(:available).set_priority(1))
|
43
|
+
|
44
|
+
|
45
|
+
Thread.stop
|
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
include Lijab
|
3
|
+
|
4
|
+
Commands::Command.define :cowsay do
|
5
|
+
usage "/cowsay <contact> <msg>"
|
6
|
+
description %q{
|
7
|
+
_______________________
|
8
|
+
< Send a message by cow >
|
9
|
+
-----------------------
|
10
|
+
\ ^__^
|
11
|
+
\ (oo)\_______
|
12
|
+
(__)\ )\/\
|
13
|
+
||----w |
|
14
|
+
|| ||}[1..-1]
|
15
|
+
|
16
|
+
def run(args)
|
17
|
+
contact, say = args.split(" ", 2).strip
|
18
|
+
if say && Main.contacts.key?(contact)
|
19
|
+
msg = "\n#{`cowsay #{say} 2>&1`}"
|
20
|
+
if $?.success?
|
21
|
+
Main.contacts[contact].send_message(msg)
|
22
|
+
else
|
23
|
+
raise Commands::CommandError, %{shell complained: "#{msg.chomp}"}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def completer(line)
|
29
|
+
contact = line.split[1] || ""
|
30
|
+
Main.contacts.completer(contact, false) if contact.empty? || !Main.contacts.key?(contact)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
include Lijab
|
3
|
+
|
4
|
+
require 'festivaltts4r'
|
5
|
+
|
6
|
+
Hooks::on_incoming_message do |contact, msg|
|
7
|
+
Thread.new do
|
8
|
+
system("aplay -q /usr/share/gajim/data/sounds/message2.wav &> /dev/null")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
#Hooks::on_incoming_message do |contact, msg|
|
13
|
+
# msg.to_speech
|
14
|
+
#end
|
15
|
+
|
16
|
+
#Hooks::on_pre_send_message do |contact, body|
|
17
|
+
# Out::inline("before sending message to #{contact}")
|
18
|
+
# "#{body}, motherfucker"
|
19
|
+
#end
|
20
|
+
|
21
|
+
#Hooks::on_post_send_message do |contact, body|
|
22
|
+
# Out::inline("after sending message to #{contact}")
|
23
|
+
#end
|
data/lib/lijab.rb
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
|
2
|
+
module Lijab
|
3
|
+
|
4
|
+
module Commands
|
5
|
+
@registered = {}
|
6
|
+
@overloaded = {}
|
7
|
+
|
8
|
+
module CommandMixin
|
9
|
+
def define_meta(*names)
|
10
|
+
class_eval do
|
11
|
+
names.each do |name|
|
12
|
+
define_method(name) do |*args|
|
13
|
+
if args.size == 0
|
14
|
+
instance_variable_get("@#{name}")
|
15
|
+
else
|
16
|
+
instance_variable_set("@#{name}", *args)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module ContactCompleterMixin
|
25
|
+
def completer(line)
|
26
|
+
_, contact = line.split(nil, 2)
|
27
|
+
Main.contacts.completer(contact, false)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class CommandError < RuntimeError
|
32
|
+
end
|
33
|
+
|
34
|
+
class Command
|
35
|
+
class << self
|
36
|
+
private :new
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.define(name, &block)
|
40
|
+
c = new
|
41
|
+
c.instance_eval(&block)
|
42
|
+
Commands::register(name.to_sym, c)
|
43
|
+
end
|
44
|
+
|
45
|
+
def completer(s)
|
46
|
+
end
|
47
|
+
|
48
|
+
def run(args)
|
49
|
+
end
|
50
|
+
|
51
|
+
extend CommandMixin
|
52
|
+
define_meta :usage, :description
|
53
|
+
end
|
54
|
+
|
55
|
+
module_function
|
56
|
+
|
57
|
+
def init
|
58
|
+
files = Dir[File.join(File.dirname(File.expand_path(__FILE__)), 'commands', '*.rb')] + \
|
59
|
+
Dir[File.join(Config.dirs[:commands], '**', '*.rb')]
|
60
|
+
|
61
|
+
files.each { |f| load f }
|
62
|
+
Config.opts[:aliases].each do |a, c|
|
63
|
+
register_alias(a, c)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def register(name, cmd)
|
68
|
+
name = name.to_sym
|
69
|
+
@overloaded[name] = @registered[name] if @registered.key?(name)
|
70
|
+
@registered[name] = cmd
|
71
|
+
end
|
72
|
+
|
73
|
+
def register_alias(name, s)
|
74
|
+
alias_cmd, alias_args = s.split(" ", 2)
|
75
|
+
alias_cmd.strip!
|
76
|
+
alias_cmd = alias_cmd[1..-1] if alias_cmd[0] == ?/
|
77
|
+
name = name[1..-1] if name[0] == ?/
|
78
|
+
|
79
|
+
Command.define name.to_sym do
|
80
|
+
description %{Alias for "#{s}"}
|
81
|
+
@alias_cmd = alias_cmd
|
82
|
+
@alias_args = alias_args
|
83
|
+
@name = name
|
84
|
+
|
85
|
+
def run(args)
|
86
|
+
Commands::run(@alias_cmd, [@alias_args, args].join(" "), true)
|
87
|
+
end
|
88
|
+
|
89
|
+
def completer(line)
|
90
|
+
args = line.split(" ", 2)[1]
|
91
|
+
Commands::completer("/#{@alias_cmd} #{@alias_args} #{args}").map do |r|
|
92
|
+
r.gsub(/\/#{@alias_cmd}\s?/, "")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def get(name)
|
99
|
+
@registered[name.to_sym]
|
100
|
+
end
|
101
|
+
|
102
|
+
def registered?(name)
|
103
|
+
@registered.key?(name.to_sym)
|
104
|
+
end
|
105
|
+
|
106
|
+
def run(cmd, args="", is_alias=false)
|
107
|
+
cmd = cmd.strip.to_sym
|
108
|
+
command = @overloaded[cmd] if is_alias
|
109
|
+
command ||= @registered[cmd]
|
110
|
+
if command
|
111
|
+
begin
|
112
|
+
command.run(args.strip)
|
113
|
+
rescue CommandError => e
|
114
|
+
Out::error("#{cmd}: #{e}", false)
|
115
|
+
end
|
116
|
+
else
|
117
|
+
Out::error("no such command: /#{cmd}", false)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def completer(line)
|
122
|
+
cmd, args = line[1..-1].split(" ", 2).strip
|
123
|
+
cmd ||= ""
|
124
|
+
|
125
|
+
matches = @registered.keys.find_all { |c| c.to_s.match(/^#{Regexp.escape(cmd)}/) }
|
126
|
+
|
127
|
+
if !cmd.empty? && (matches.length == 1 || args) && registered?(cmd)
|
128
|
+
(@registered[cmd.to_sym].completer(line) || []).map { |s| "/#{cmd} #{s}" }
|
129
|
+
else
|
130
|
+
matches.map { |k| "/#{k}" }
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
attr_reader :registered
|
135
|
+
module_function :registered
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|