lijab 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|