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
@@ -0,0 +1,101 @@
|
|
1
|
+
|
2
|
+
module Lijab
|
3
|
+
module Commands
|
4
|
+
|
5
|
+
module ContactsCommandMixin
|
6
|
+
SORTBY = ["status", "alpha"]
|
7
|
+
|
8
|
+
def completer(line)
|
9
|
+
sortby = line.split[1] || ""
|
10
|
+
if SORTBY.grep(sortby).empty?
|
11
|
+
SORTBY.grep(/^#{Regexp.escape(sortby)}/)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def group_contacts(contacts)
|
16
|
+
grouped = {}
|
17
|
+
contacts.each do |jid,contact|
|
18
|
+
groups = contact.roster_item.groups
|
19
|
+
if groups.empty?
|
20
|
+
(grouped["<no group>"] ||= []) << contact
|
21
|
+
else
|
22
|
+
groups.each { |g| (grouped[g] ||= []) << contact }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
grouped = grouped.sort_by { |g,c| g }
|
27
|
+
end
|
28
|
+
|
29
|
+
def print_contacts(sort_by_status=false, online_only=false)
|
30
|
+
if sort_by_status
|
31
|
+
contacts = Main.contacts.sort { |a, b| -(a[1].presence <=> b[1].presence) }
|
32
|
+
else
|
33
|
+
contacts = Main.contacts.sort_by { |j,c| c.simple_name }
|
34
|
+
end
|
35
|
+
|
36
|
+
if Config.opts[:show_groups_in_contact_list]
|
37
|
+
grouped = group_contacts(contacts)
|
38
|
+
else
|
39
|
+
grouped = {nil => contacts.map { |j,c| c }}
|
40
|
+
end
|
41
|
+
|
42
|
+
s = []
|
43
|
+
grouped.each do |group, contactz|
|
44
|
+
if online_only
|
45
|
+
next unless contactz.any? { |c| c.online? }
|
46
|
+
end
|
47
|
+
|
48
|
+
s << " #{group} ".on_blue if group
|
49
|
+
contactz.each do |contact|
|
50
|
+
unless online_only && !contact.online?
|
51
|
+
main = contact.presence
|
52
|
+
s << "* #{contact.simple_name} #{main.pretty(true)} " \
|
53
|
+
"(#{main.priority || 0}) [#{main.from || contact.jid}]"
|
54
|
+
|
55
|
+
if online_only && contact.roster_item.presences.length > 1
|
56
|
+
contact.roster_item.presences.each do |p|
|
57
|
+
if p.from != main.from
|
58
|
+
s << " #{p.from} #{p.pretty(true)} (#{p.priority || 0})"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
Out::put(s.join("\n")) unless s.empty?
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
Command.define :contacts do
|
72
|
+
usage "/contacts [status|alpha]"
|
73
|
+
description "Show a list of all contacts. Sorted alphabetically or by status."
|
74
|
+
|
75
|
+
SORTBY = ["status", "alpha"]
|
76
|
+
|
77
|
+
def run(args)
|
78
|
+
print_contacts(args.split[0] == "status")
|
79
|
+
end
|
80
|
+
|
81
|
+
class << self
|
82
|
+
include ContactsCommandMixin
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
Command.define :who do
|
87
|
+
usage "/who [status|alpha]"
|
88
|
+
description "Show a list of online contacts. Sorted alphabetically or by status."
|
89
|
+
|
90
|
+
def run(args)
|
91
|
+
print_contacts(args.split[0] == "status", true)
|
92
|
+
end
|
93
|
+
|
94
|
+
class << self
|
95
|
+
include ContactsCommandMixin
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
module Lijab
|
3
|
+
module Commands
|
4
|
+
|
5
|
+
Command.define :set do
|
6
|
+
usage "/set <option> [<value>]"
|
7
|
+
description "Modify the options. Print the current value if no <value> is given.\n" \
|
8
|
+
"See #{Config.files[:config]} for the available options."
|
9
|
+
def run(args)
|
10
|
+
option, value = args.split(nil, 2).strip
|
11
|
+
|
12
|
+
option = option.to_sym if option
|
13
|
+
|
14
|
+
if !(Config.opts[option].is_a?(String) ||
|
15
|
+
Config.opts[option].is_a?(Numeric) ||
|
16
|
+
[true, false, nil].include?(Config.opts[option])) &&
|
17
|
+
Config.opts.key?(option)
|
18
|
+
raise CommandError, %{can't change "#{option} with /set"}
|
19
|
+
elsif !Config.opts.key?(option)
|
20
|
+
raise CommandError, %{no such option "#{option}"}
|
21
|
+
end
|
22
|
+
|
23
|
+
if value && !value.empty?
|
24
|
+
begin
|
25
|
+
val = YAML.load(value)
|
26
|
+
#raise TypeError unless val.is_a?(Config.opts[option].class)
|
27
|
+
Config.opts[option] = val
|
28
|
+
rescue
|
29
|
+
Out::error("invalid value", false)
|
30
|
+
end
|
31
|
+
else
|
32
|
+
Out::put(YAML.dump(Config.opts[option])[4..-1].chomp)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def completer(line)
|
38
|
+
option = line.split(nil, 2).strip[1] || ""
|
39
|
+
Config.opts.keys.find_all do |k|
|
40
|
+
k.to_s =~ /^#{Regexp.escape(option)}/ &&
|
41
|
+
(Config.opts[k].is_a?(String) ||
|
42
|
+
Config.opts[k].is_a?(Numeric) ||
|
43
|
+
[true, false, nil].include?(Config.opts[k]))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
|
2
|
+
module Lijab
|
3
|
+
module Commands
|
4
|
+
|
5
|
+
Command.define :help do
|
6
|
+
usage "/help [<command> | commands]"
|
7
|
+
description "Get some help."
|
8
|
+
|
9
|
+
def run(args)
|
10
|
+
if args.empty?
|
11
|
+
s = %Q{
|
12
|
+
When in doubt, hit <tab>.
|
13
|
+
|
14
|
+
Some general hints:
|
15
|
+
|
16
|
+
Run "lijab -a <name>" to connect to the account named <name>.
|
17
|
+
|
18
|
+
Tab on an empty line will try to complete online contacts.
|
19
|
+
If there are no online contact matches for what you typed, offline contacts will also be
|
20
|
+
considered.
|
21
|
+
|
22
|
+
You can tab-complete specific resources of a contact by typing the contact name
|
23
|
+
followed by an @ character, e.g. somecontact@<tab> will complete all the available
|
24
|
+
resources for the contact and a message can be sent to that specific resource.
|
25
|
+
|
26
|
+
Config/logs folder is at #{Config.basedir}
|
27
|
+
|
28
|
+
Put your custom commands in #{Config.dirs[:commands]}
|
29
|
+
Check out the files in <install-path>/lib/lijab/commands/ for some examples.
|
30
|
+
|
31
|
+
Put your custom hooks in #{Config.dirs[:hooks]}
|
32
|
+
|
33
|
+
Send mails to quuxbaz@gmail.com to complain about the lack of documentation :-)
|
34
|
+
|
35
|
+
}.gsub!(/^ */, '')
|
36
|
+
Out::put(s)
|
37
|
+
else
|
38
|
+
if args == "commands"
|
39
|
+
Out::put
|
40
|
+
Commands::registered.each do |name, cmd|
|
41
|
+
Out::put(%{#{cmd.usage || "/#{name}"}}.magenta)
|
42
|
+
Out::put("#{cmd.description}\n\n")
|
43
|
+
end
|
44
|
+
else
|
45
|
+
cmd = Commands::get(args)
|
46
|
+
if cmd
|
47
|
+
s = "usage: #{cmd.usage}\n\n" if cmd.usage
|
48
|
+
s = "#{s}#{cmd.description}"
|
49
|
+
Out::put(s)
|
50
|
+
else
|
51
|
+
raise CommandError, %(No such command "#{args}")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def completer(line)
|
58
|
+
help_cmd, rest = line.split(" ", 2)
|
59
|
+
rest ||= ""
|
60
|
+
|
61
|
+
m = "commands" =~ /^#{Regexp.escape(rest)}/ ? ["commands"] : []
|
62
|
+
|
63
|
+
rest = "/#{rest}"
|
64
|
+
|
65
|
+
m += Commands::completer(rest).map { |c| c[1..-1] } if rest.split(" ", 2).length == 1
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
Command.define :history do
|
70
|
+
usage "/history [<contact>] [<limit>]"
|
71
|
+
description "Show the message history with a <contact>, or all the contacts."
|
72
|
+
|
73
|
+
def run(args)
|
74
|
+
contact, limit = args.split(" ", 2).strip
|
75
|
+
limit ||= 10
|
76
|
+
|
77
|
+
if contact
|
78
|
+
raise CommandError, %(No contact named "#{contact}) unless Main.contacts.key?(contact)
|
79
|
+
m = Main.contacts[contact].history.last(limit.to_i)
|
80
|
+
else
|
81
|
+
m = HistoryHandler::last(limit.to_i)
|
82
|
+
end
|
83
|
+
Out::history(*m)
|
84
|
+
end
|
85
|
+
|
86
|
+
class << self
|
87
|
+
include ContactCompleterMixin
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
Command.define :multiline do
|
92
|
+
usage "/multiline <contact> [<first_line>]"
|
93
|
+
description "Enter multiline mode, meaning, send a multiline message to a contact.\n" \
|
94
|
+
"Ctrl-d in an empty line exits multiline mode and sends the message."
|
95
|
+
|
96
|
+
def run(args)
|
97
|
+
contact, first_line = args.split(" ", 2).strip
|
98
|
+
first_line = "#{contact}: #{first_line}"
|
99
|
+
InputHandler::multiline(true, first_line)
|
100
|
+
end
|
101
|
+
|
102
|
+
class << self
|
103
|
+
include ContactCompleterMixin
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
Command.define :quit do
|
108
|
+
usage "/quit"
|
109
|
+
description "Quit lijab"
|
110
|
+
|
111
|
+
def run(args)
|
112
|
+
Main.quit
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# TODO: make a generic option changer?
|
117
|
+
Command.define :show_status_changes do
|
118
|
+
usage "/show_status_changes yes|no"
|
119
|
+
description "Enable/disable printing the contacts' status changes. Can get quite spammish."
|
120
|
+
|
121
|
+
def run(args)
|
122
|
+
if !args || args.empty?
|
123
|
+
Out::put(Config.opts[:show_status_changes] ? "yes" : "no")
|
124
|
+
else
|
125
|
+
Config.opts[:show_status_changes] = args.strip == "yes"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
module Lijab
|
3
|
+
module Commands
|
4
|
+
|
5
|
+
Command.define :priority do
|
6
|
+
usage "/priority [<priority>]"
|
7
|
+
description "Change the jabber priority. Number must be between -127 and 127.\n" \
|
8
|
+
"Show current priority if no argument is given."
|
9
|
+
|
10
|
+
def run(args)
|
11
|
+
if args.strip.empty?
|
12
|
+
Out::put("Current priority is #{Main.presence.priority}")
|
13
|
+
return
|
14
|
+
end
|
15
|
+
|
16
|
+
begin
|
17
|
+
p = Integer(args)
|
18
|
+
rescue ArgumentError
|
19
|
+
raise Commands::CommandError, %{"#{args}" is not a valid integer}
|
20
|
+
end
|
21
|
+
|
22
|
+
raise Commands::CommandError, "priority must be between -127 and 127" unless (-127..127).include?(p)
|
23
|
+
|
24
|
+
Main.set_priority(p)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
Command.define :status do
|
29
|
+
usage "/status [available|away|chat|xa|dnd|invisible] [<message>]"
|
30
|
+
description "Set your status.\n" \
|
31
|
+
"If no status is given, keep the current and set the status message.\n" \
|
32
|
+
"If no message is given, keep the current status and clear the message.\n" \
|
33
|
+
"If no arguments are given, print the current status."
|
34
|
+
|
35
|
+
STATUSES = ["available", "away", "chat", "xa", "dnd", "invisible"]
|
36
|
+
|
37
|
+
def run(args)
|
38
|
+
status, message = args.split(" ", 2).strip
|
39
|
+
|
40
|
+
unless status
|
41
|
+
p = Main.presence
|
42
|
+
Out::put("#{Config.jid} (#{p.priority || 0}) #{p.pretty(true)}")
|
43
|
+
return
|
44
|
+
end
|
45
|
+
|
46
|
+
unless STATUSES.include?(status)
|
47
|
+
message = "#{status} #{message}".strip
|
48
|
+
status = nil
|
49
|
+
end
|
50
|
+
|
51
|
+
Main.set_status(status && status.to_sym, message)
|
52
|
+
end
|
53
|
+
|
54
|
+
def completer(line)
|
55
|
+
status = line.split[1] || ""
|
56
|
+
if STATUSES.grep(status).empty?
|
57
|
+
STATUSES.grep(/^#{Regexp.escape(status)}/)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
|
2
|
+
module Lijab
|
3
|
+
module Commands
|
4
|
+
Command.define :add do
|
5
|
+
usage "/add <user@server>"
|
6
|
+
description "Add a user to your roster."
|
7
|
+
|
8
|
+
def run(args)
|
9
|
+
Main.contacts.add(args)
|
10
|
+
Out::put("subscription request sent to #{args}")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
Command.define :remove do
|
15
|
+
usage "/remove <user@server>"
|
16
|
+
description "Remove a user from your roster."
|
17
|
+
|
18
|
+
def run(args)
|
19
|
+
unless Main.contacts.remove(args)
|
20
|
+
raise CommandError, "no contact found for #{args}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class << self
|
25
|
+
include ContactCompleterMixin
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# TODO: <user@server | all>
|
30
|
+
Command.define :requests do
|
31
|
+
usage "/requests [accept|accept_and_add|decline <user@server>]"
|
32
|
+
description "Accept/decline a user's request to see your status.\n" \
|
33
|
+
"Print pending requests if no argument given." \
|
34
|
+
|
35
|
+
ACTIONS = ["accept", "accept_and_add", "decline"]
|
36
|
+
|
37
|
+
def run(args)
|
38
|
+
action, addr = args.split(nil, 2).strip
|
39
|
+
|
40
|
+
if action
|
41
|
+
unless ACTIONS.include?(action)
|
42
|
+
raise CommandError, "action must be accept, accept_and_add or decline"
|
43
|
+
end
|
44
|
+
raise CommandError, "need the user's address" unless addr and !addr.empty?
|
45
|
+
|
46
|
+
if ["accept", "accept_and_add"].include?(action)
|
47
|
+
success = Main.contacts.process_request(addr, :accept)
|
48
|
+
Main.contacts.add(addr) if success && action == "accept_and_add"
|
49
|
+
else
|
50
|
+
success = Main.contacts.process_request(addr, :decline)
|
51
|
+
end
|
52
|
+
|
53
|
+
raise CommandError, "no pending request from #{addr}" unless success
|
54
|
+
else
|
55
|
+
if Main.contacts.has_subscription_requests?
|
56
|
+
Out::put("pending requests from:")
|
57
|
+
Out::put(Main.contacts.subscription_requests.join("\n"))
|
58
|
+
else
|
59
|
+
Out::put("no pending requests")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def completer(line)
|
65
|
+
_, action, addr = line.split(nil, 3)
|
66
|
+
|
67
|
+
if !addr
|
68
|
+
ACTIONS.grep(/^#{Regexp.escape(action)}/)
|
69
|
+
elsif addr && ACTIONS.include?(action)
|
70
|
+
Main.contacts.subscription_requests.grep(/^#{Regexp.escape(addr)}/).map do |c|
|
71
|
+
"#{action} #{c}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
data/lib/lijab/config.rb
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
|
2
|
+
module Lijab
|
3
|
+
|
4
|
+
module Config
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def init(args)
|
8
|
+
@opts = {}
|
9
|
+
@dirs = {}
|
10
|
+
@files = {}
|
11
|
+
@accounts = []
|
12
|
+
@account = nil
|
13
|
+
|
14
|
+
setup_basedir(args[:basedir])
|
15
|
+
read_accounts(args[:account])
|
16
|
+
read_options()
|
17
|
+
|
18
|
+
@jid = Jabber::JID.new("#{@account[:jabberid]}")
|
19
|
+
@jid.resource ||= "lijab#{(0...5).map{rand(10).to_s}.join}"
|
20
|
+
@account[:server] ||= @jid.domain
|
21
|
+
|
22
|
+
create_account_dirs()
|
23
|
+
end
|
24
|
+
|
25
|
+
def setup_basedir(basedir)
|
26
|
+
# xdg? meh
|
27
|
+
#xdg = ENV["XDG_CONFIG_HOME"]
|
28
|
+
#xdg && File.join(xdg, "lijab") ||
|
29
|
+
|
30
|
+
@basedir = basedir ||
|
31
|
+
ENV["LIJABDIR"] ||
|
32
|
+
"~/.lijab"
|
33
|
+
@basedir = File.expand_path(@basedir)
|
34
|
+
|
35
|
+
unless File.directory?(@basedir)
|
36
|
+
puts "Creating #{@basedir} with the default configs"
|
37
|
+
end
|
38
|
+
|
39
|
+
%w{accounts commands hooks}.each do |d|
|
40
|
+
@dirs[d.to_sym] = path = File.join(@basedir, d)
|
41
|
+
FileUtils.mkdir_p(path)
|
42
|
+
end
|
43
|
+
|
44
|
+
@files[:accounts] = path = File.join(@basedir, "accounts.yml")
|
45
|
+
File.open(path, 'w') { |f| f.puts(DEFAULT_ACCOUNTS_FILE) } unless File.file?(path)
|
46
|
+
|
47
|
+
@files[:config] = File.join(@basedir, "config.yml")
|
48
|
+
dump_config_file(true)
|
49
|
+
end
|
50
|
+
|
51
|
+
def dump_config_file(default=false, clobber=false)
|
52
|
+
if !File.file?(@files[:config]) || clobber
|
53
|
+
File.open(@files[:config], 'w') do |f|
|
54
|
+
DEFAULT_OPTIONS.each do |a|
|
55
|
+
if a[2]
|
56
|
+
f.puts
|
57
|
+
a[2].each { |l| f.puts("# #{l}") }
|
58
|
+
end
|
59
|
+
v = default ? a[1] : @opts[a[0]]
|
60
|
+
f.puts(YAML.dump({a[0] => v})[5..-1].chomp)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def read_accounts(account)
|
67
|
+
File.open(@files[:accounts]) do |f|
|
68
|
+
YAML.load_documents(f) { |a| @accounts << a }
|
69
|
+
end
|
70
|
+
|
71
|
+
errors = []
|
72
|
+
errors << "need at least one account!" if @accounts.empty?
|
73
|
+
|
74
|
+
@accounts.each do |a|
|
75
|
+
a[:port] ||= a[:use_ssl] ? 5223 : 5222
|
76
|
+
|
77
|
+
errors << "account #{a} needs a name" unless a.key?(:name)
|
78
|
+
errors << "account #{a[:name] || a} needs a jabberid" unless a.key?(:jabberid)
|
79
|
+
end
|
80
|
+
|
81
|
+
@account = account ? @accounts.find { |a| a[:name] == account} : @accounts[0]
|
82
|
+
|
83
|
+
errors << "no account with name #{account} in #{@accounts_file}" if account && !@account
|
84
|
+
|
85
|
+
errors.each do |e|
|
86
|
+
STDERR.puts("#{File.basename($0)}: error: #{e}")
|
87
|
+
end
|
88
|
+
|
89
|
+
exit(1) unless errors.empty?
|
90
|
+
end
|
91
|
+
|
92
|
+
def read_options
|
93
|
+
# FIXME: error check / validate
|
94
|
+
|
95
|
+
@opts = Hash[*DEFAULT_OPTIONS.collect { |a| [a[0], a[1]] }.flatten]
|
96
|
+
@opts.merge!(YAML.load_file(@files[:config]))
|
97
|
+
end
|
98
|
+
|
99
|
+
def create_account_dirs
|
100
|
+
@accounts.each do |a|
|
101
|
+
a[:dir] = File.join(@dirs[:accounts], @jid.strip.to_s)
|
102
|
+
a[:log_dir] = File.join(a[:dir], "logs")
|
103
|
+
a[:typed] = File.join(a[:dir], "typed_history")
|
104
|
+
|
105
|
+
[:dir, :log_dir].each { |s| FileUtils.mkdir_p(a[s]) }
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
DEFAULT_OPTIONS = [
|
110
|
+
[:datetime_format, "%H:%M:%S", ["Time formatting (leave empty to disable timestamps)"]],
|
111
|
+
[:history_datetime_format, "%Y-%b-%d %H:%M:%S"],
|
112
|
+
[:autocomplete_online_first, true,
|
113
|
+
["When completing contacts try to find matches for online contacts, and if none",
|
114
|
+
"is found try to find matches on all of them. Otherwise always match every",
|
115
|
+
"contact."]],
|
116
|
+
[:show_status_changes, true, ["Show changes in contacts' status"]],
|
117
|
+
[:show_groups_in_contact_list, false, ["Group contacts in contact list"]],
|
118
|
+
[:ctrl_c_quits, false,
|
119
|
+
["ctrl+c quits the program if enabled, otherwise ctrl+c ignores whatever is",
|
120
|
+
"typed and you get a clean prompt, and ctrl+d on a clean line exits lijab,",
|
121
|
+
"terminal style."]],
|
122
|
+
[:terminal_bell_on_message, true,
|
123
|
+
["Ring the terminal bell on incoming message.",
|
124
|
+
"Useful for setting the urgent hint on the terminal window:",
|
125
|
+
"Set as so in your ~/.Xdefaults, might have to run xrdb -merge ~/.Xdefaults afterwards",
|
126
|
+
"XTerm*bellIsUrgent: true",
|
127
|
+
"or",
|
128
|
+
"URxvt*urgentOnBell: true",
|
129
|
+
"or just look it up on your terminal's man page, don't be lazy."]],
|
130
|
+
[:status_priorities,
|
131
|
+
{:chat => 55, :available => 50, :away => 40, :xa => 30, :dnd => 20},
|
132
|
+
["Default priority for each status"]],
|
133
|
+
[:aliases, {"/h" => "/history", "/exit" => "/quit"},
|
134
|
+
["Command aliases.",
|
135
|
+
"<command_alias> : <existing_command>",
|
136
|
+
"Commands can be overloaded.",
|
137
|
+
"For instance /who could be redefined like so to sort by status by default.",
|
138
|
+
"/who : /who status"]]
|
139
|
+
]
|
140
|
+
|
141
|
+
DEFAULT_ACCOUNTS_FILE = %Q{
|
142
|
+
# Accounts go here. Separate each one with ---
|
143
|
+
# First one is the default.
|
144
|
+
|
145
|
+
#---
|
146
|
+
#:name : an_account # the account name
|
147
|
+
#:jabberid : fisk@example.com/lijab # the resource is optional
|
148
|
+
#:password : frosk # optional, will prompt if not present
|
149
|
+
#:server : localhost # optional, will use the jid domain if not present
|
150
|
+
#:port : 5222 # optional
|
151
|
+
#:use_ssl : no # deprecated in jabber, but might help sometimes
|
152
|
+
#:log : yes # yes|no ; default no
|
153
|
+
|
154
|
+
#---
|
155
|
+
#:name : another_account
|
156
|
+
#:jabberid : another_user@example.com/lijab
|
157
|
+
|
158
|
+
#---
|
159
|
+
#:name : gmail_account
|
160
|
+
#:jabberid : blah@gmail.com/lijab
|
161
|
+
#:server : talk.google.com
|
162
|
+
## might wanna try use_ssl if the normal settings don't work (e.g. in ubuntu afaik)
|
163
|
+
##:port : 5223
|
164
|
+
##:use_ssl : yes
|
165
|
+
#:log : yes
|
166
|
+
|
167
|
+
}.gsub!(/^ */, '')
|
168
|
+
|
169
|
+
attr_reader :jid, :account, :basedir, :dirs, :files, :opts
|
170
|
+
module_function :jid, :account, :basedir, :dirs, :files, :opts
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|