ratchet 0.3.0

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.
Files changed (49) hide show
  1. data/gem_bin/ratchet +23 -0
  2. data/lib/ratchet.rb +613 -0
  3. data/lib/ratchet/aliases.rb +106 -0
  4. data/lib/ratchet/bufferparser.rb +409 -0
  5. data/lib/ratchet/commandbuffer.rb +66 -0
  6. data/lib/ratchet/commandparser.rb +668 -0
  7. data/lib/ratchet/configuration.rb +278 -0
  8. data/lib/ratchet/connections.rb +403 -0
  9. data/lib/ratchet/constants.rb +111 -0
  10. data/lib/ratchet/contrib/instance_exec.rb +21 -0
  11. data/lib/ratchet/eventparser.rb +486 -0
  12. data/lib/ratchet/gtk/bufferlistview.rb +514 -0
  13. data/lib/ratchet/gtk/bufferview.rb +167 -0
  14. data/lib/ratchet/gtk/configwindow.rb +229 -0
  15. data/lib/ratchet/gtk/connectionwindow.rb +218 -0
  16. data/lib/ratchet/gtk/keybinding.rb +356 -0
  17. data/lib/ratchet/gtk/linkwindow.rb +137 -0
  18. data/lib/ratchet/gtk/mainwindow.rb +504 -0
  19. data/lib/ratchet/gtk/networkpresenceconf.rb +567 -0
  20. data/lib/ratchet/gtk/pluginconfig.rb +94 -0
  21. data/lib/ratchet/gtk/pluginwindow.rb +146 -0
  22. data/lib/ratchet/gtk/userlistview.rb +161 -0
  23. data/lib/ratchet/help.rb +64 -0
  24. data/lib/ratchet/items.rb +271 -0
  25. data/lib/ratchet/lines.rb +63 -0
  26. data/lib/ratchet/networks.rb +652 -0
  27. data/lib/ratchet/plugins.rb +616 -0
  28. data/lib/ratchet/queue.rb +47 -0
  29. data/lib/ratchet/ratchet-version.rb +21 -0
  30. data/lib/ratchet/replies.rb +134 -0
  31. data/lib/ratchet/replyparser.rb +441 -0
  32. data/lib/ratchet/tabcomplete.rb +98 -0
  33. data/lib/ratchet/users.rb +237 -0
  34. data/lib/ratchet/utils.rb +178 -0
  35. data/share/defaults.yaml +169 -0
  36. data/share/glade/config.glade +2634 -0
  37. data/share/glade/connect.glade +950 -0
  38. data/share/glade/keybindings.glade +109 -0
  39. data/share/glade/linkwindow.glade +188 -0
  40. data/share/glade/mainwindow.glade +335 -0
  41. data/share/glade/network-presences.glade +1373 -0
  42. data/share/glade/pluginconf.glade +97 -0
  43. data/share/glade/plugins.glade +360 -0
  44. data/share/plugins/colorewrite.rb +193 -0
  45. data/share/plugins/highlighter.rb +115 -0
  46. data/share/plugins/mpdplay.rb +123 -0
  47. data/share/plugins/numberswitcher.rb +30 -0
  48. data/share/plugins/sysinfo.rb +82 -0
  49. metadata +96 -0
@@ -0,0 +1,98 @@
1
+ =begin
2
+ This file is part of the Ratchet project, a client for Icecap.
3
+ Copyright (C) 2005-6 Andrew Thompson
4
+
5
+ This program is free software; you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation; either version 2 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program; if not, write to the Free Software
17
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
+ =end
19
+
20
+ #### tabcomplete.rb ####
21
+ # A tabcomplete class and mixin
22
+ ####
23
+
24
+ module Ratchet
25
+ class TabComplete
26
+ #class that stores the results of a tabcomplete so it can be reused
27
+ attr_reader :results
28
+ def initialize(substr, list)
29
+ @results = []
30
+ match(substr, list)
31
+ @position = 0
32
+ end
33
+
34
+ def match(substr, list)
35
+ return if substr.length == 0
36
+ list.each do |item|
37
+ if item[0, substr.length].downcase == substr.downcase
38
+ @results.push(item)
39
+ end
40
+ end
41
+ end
42
+
43
+ def firstmatch
44
+ return @results[0]
45
+ end
46
+
47
+ def succ
48
+ @position += 1
49
+ @position = 0 if @position >= @results.length
50
+ return @results[@position]
51
+ end
52
+ end
53
+
54
+ #mixin for adding to buffers
55
+ module TabCompleteModule
56
+ def tabcomplete(substr)
57
+ # puts self
58
+ if !@tabcomplete
59
+ if substr[0].chr == '/'
60
+ list = @main.command_list
61
+ elsif self.respond_to? :users and !self.network != self and !users.nil?
62
+ # puts self
63
+ if @config['tabcompletesort'] == 'activity'
64
+ #sort by activity
65
+ list = @users.users.sort{|x, y| y.lastspoke <=> x.lastspoke}
66
+ else
67
+ #otherwise, sort by name
68
+ list = @users.users.sort
69
+ end
70
+
71
+ currentuser = @users[username]
72
+
73
+ if list.include?(currentuser)
74
+ list.delete(currentuser)
75
+ list.push(currentuser)
76
+ end
77
+ list = list.map{|x| x.name}
78
+ else
79
+ return nil
80
+ end
81
+
82
+ @tabcomplete = TabComplete.new(substr, list)
83
+ if @tabcomplete.firstmatch
84
+ return @tabcomplete.firstmatch
85
+ else
86
+ clear_tabcomplete
87
+ return nil
88
+ end
89
+ else
90
+ return @tabcomplete.succ
91
+ end
92
+ end
93
+
94
+ def clear_tabcomplete
95
+ @tabcomplete = nil
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,237 @@
1
+ =begin
2
+ This file is part of the Ratchet project, a client for Icecap.
3
+ Copyright (C) 2005-6 Andrew Thompson
4
+
5
+ This program is free software; you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation; either version 2 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program; if not, write to the Free Software
17
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
+ =end
19
+
20
+ #### users.rb ####
21
+ # Contains classes for Users and a class to contain many users
22
+ # Channel user is a user with some channel specific modes attached
23
+ # the userlists just contain all users for that channel/network
24
+ ####
25
+
26
+ module Ratchet
27
+ class User
28
+ attr_reader :hostname, :name, :lastspoke
29
+ attr_writer :hostname
30
+ def initialize(name)
31
+ @hostname = nil
32
+ @name = name
33
+ time = Time.new
34
+ #time = time - $main.drift if $config['canonicaltime'] == 'server'
35
+ @lastspoke = time
36
+ end
37
+
38
+ def rename(name)
39
+ @name = name
40
+ end
41
+
42
+ def <=>(object)
43
+ a = @name.downcase
44
+ b = object.name.downcase
45
+
46
+ return a <=> b
47
+ end
48
+
49
+ def lastspoke=(time)
50
+ #time = time.to_i + $main.drift if $config['canonicaltime'] == 'client'
51
+ @lastspoke = Time.at(time.to_i)
52
+ end
53
+
54
+ def comparetostring(string)
55
+ a = @name.downcase
56
+ b = string.downcase
57
+
58
+ return a <=> b
59
+ end
60
+ end
61
+
62
+ #class that contains a user, as well as channel specific info like modes
63
+ class ChannelUser < User
64
+ Modes = ['', 'voice', 'op'].reverse
65
+ #Modes = {'op' => 2, 'voice'=>1}
66
+ #Modes.default = 0
67
+ ModeSymbols = {'op'=>'@', 'voice'=>'+'}
68
+ ModeSymbols.default = ''
69
+ #SymbolModes = {'@'=> 'op', '+'=>'voice'}
70
+ #SymbolModes.default = ''
71
+ attr_reader :mode
72
+ def initialize(user)
73
+ @user = user
74
+ @mode = ''
75
+ end
76
+
77
+ def hostname=(hostname)
78
+ @user.hostname = hostname
79
+ end
80
+
81
+ def hostname
82
+ @user.hostname
83
+ end
84
+
85
+ def name
86
+ @user.name
87
+ end
88
+
89
+ def lastspoke
90
+ @user.lastspoke
91
+ end
92
+
93
+ def lastspoke=(time)
94
+ @user.lastspoke(time)
95
+ end
96
+
97
+ def mode_symbol
98
+ ModeSymbols[mode]
99
+ end
100
+
101
+ def mode=(mode)
102
+ mode ||= ''
103
+ @mode = mode
104
+ end
105
+ end
106
+
107
+ class UserList
108
+ attr_reader :users
109
+ def initialize
110
+ @users = []
111
+ super
112
+ end
113
+
114
+ def create(name, hostname = nil)
115
+ return if self.include?(name)
116
+ new = User.new(name)
117
+ new.hostname = hostname
118
+ @users.push(new)
119
+ return new
120
+ end
121
+
122
+ def add(user)
123
+ return if self.include?(user)
124
+ @users.push(user)
125
+ end
126
+
127
+ def include?(newuser)
128
+ if newuser.respond_to? :name
129
+ @users.each do |user|
130
+ if user.name == newuser.name
131
+ return true
132
+ end
133
+ end
134
+ elsif newuser
135
+ @users.each do |user|
136
+ if user.name == newuser
137
+ return true
138
+ end
139
+ end
140
+ end
141
+ false
142
+ end
143
+
144
+ def remove(name)
145
+ i = 0
146
+ @users.each do |user|
147
+ if user.name == name
148
+ @users.delete_at(i)
149
+ #@users.sort!
150
+ return
151
+ end
152
+ i += 1
153
+ end
154
+ end
155
+
156
+ def[](name)
157
+ result = nil
158
+ @users.each do |user|
159
+ if (user.respond_to? :name and user.name == name)
160
+ result = user
161
+ end
162
+ end
163
+ return result
164
+ end
165
+
166
+ def length
167
+ @users.length
168
+ end
169
+ end
170
+
171
+ class ChannelUserList < UserList
172
+ attr_accessor :view
173
+ def include?(newuser)
174
+ if newuser.class == ChannelUser
175
+ @users.each do |user|
176
+ if user.name == newuser.name
177
+ return true
178
+ end
179
+ end
180
+ else
181
+ @users.each do |user|
182
+ if user.name == newuser
183
+ return true
184
+ end
185
+ end
186
+ end
187
+ false
188
+ end
189
+
190
+ def summarize
191
+ opcount = @users.select{|x| x.mode == 'op'}.to_a.length
192
+ voicecount = @users.select{|x| x.mode == 'voice'}.to_a.length
193
+ total = @users.length
194
+ "#{opcount.to_s+' ops, ' if opcount > 0}#{voicecount.to_s+' voiced, ' if voicecount > 0}#{total} total"
195
+ end
196
+
197
+ def remove(user)
198
+ super
199
+ @view.remove_user(user) if @view
200
+ @view.summary = summarize if @view
201
+ end
202
+
203
+ def add(user, sync=true)
204
+ user = ChannelUser.new(user)
205
+ return user if self.include?(user)
206
+ @users.push(user)
207
+ if sync
208
+ sort
209
+ @view.add_user(user, @users.index(user)) if @view
210
+ @view.summary = summarize if @view
211
+ end
212
+ user
213
+ end
214
+
215
+ def reorder(user)
216
+ #~ @view.update(@users.index(user), user)
217
+ #~ oldusers = @users.dup
218
+ oldposition = @users.index(user)
219
+ sort
220
+ newposition = @users.index(user)
221
+ #~ order = @users.map{|x| oldusers.index(x)}
222
+ @view.reorder(oldposition, newposition, user) if @view
223
+ @view.summary = summarize if @view
224
+ end
225
+
226
+ def fill_view
227
+ @view.fill(self) if @view
228
+ @view.summary = summarize if @view
229
+ end
230
+
231
+ def sort
232
+ # puts 'sorting'
233
+ @users = @users.sort_by{|x| [ChannelUser::Modes.index(x.mode), x.name.downcase]}
234
+ #puts @users.inspect
235
+ end
236
+ end
237
+ end
@@ -0,0 +1,178 @@
1
+ =begin
2
+ This file is part of the Ratchet project, a client for Icecap.
3
+ Copyright (C) 2005-6 Andrew Thompson
4
+
5
+ This program is free software; you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation; either version 2 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program; if not, write to the Free Software
17
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
+ =end
19
+
20
+ #### utils.rb ####
21
+ # This file contains some additions to base classes
22
+ # and some other small utility snippets
23
+ ####
24
+
25
+ class String
26
+ def numeric?
27
+ return false if self.scan('.').length > 1 #more then one floating points - bad
28
+ if to_i == 0 and self != '0'
29
+ return false
30
+ end
31
+ true
32
+ end
33
+ end
34
+
35
+ module Ratchet
36
+ #A class that tries to make sure only one instance is allowed at a time
37
+ class SingleWindow
38
+ #override the constructor
39
+ def self.new(*args)
40
+ return @instance if @instance #this is a class instance var, FYI
41
+ @instance = super
42
+ @instance
43
+ end
44
+
45
+ #clean up a dead instance
46
+ def self.destroy
47
+ @instance = nil
48
+ end
49
+
50
+ #show and/or raise a window
51
+ def show
52
+ @window.show_all
53
+ @window.present
54
+ end
55
+ end
56
+
57
+ class Color
58
+ def initialize(r, g, b)
59
+ @r, @g, @b = r, g, b
60
+ end
61
+
62
+ def to_a
63
+ [@r, @g, @b]
64
+ end
65
+
66
+ def to_hex
67
+ hex = '#'
68
+ to_a.each do |c|
69
+ e = c >> 8
70
+ d = e.to_s(16)
71
+ if d.length == 1
72
+ d = '0'+d
73
+ end
74
+ hex += d
75
+ end
76
+ hex
77
+ end
78
+
79
+ def to_256
80
+ res = []
81
+ to_a.each do |c|
82
+ t = c >> 8
83
+ res << t
84
+ end
85
+ return res
86
+ end
87
+
88
+ def self.hex_to_a(string)
89
+ r = string[0, 2].hex
90
+ g = string[1, 2].hex
91
+ b = string[4, 2].hex
92
+ [r,g,b]
93
+ end
94
+
95
+ def self.a_to_hex(a)
96
+ puts a.class
97
+ res = ''
98
+ a.each do |o|
99
+ o = 255 if o > 255
100
+ o = o.to_s(16)
101
+ if o.length == 1
102
+ o = '0'+o
103
+ end
104
+ res << o
105
+ end
106
+ res
107
+ end
108
+ end
109
+ end
110
+
111
+ def duration(seconds, precision=2)
112
+
113
+ if seconds < 0
114
+ seconds *= -1
115
+ negative = true
116
+ end
117
+
118
+ t = Time.at(seconds)
119
+ t.gmtime
120
+
121
+ seconds = t.strftime('%S').to_i
122
+ minutes = t.strftime('%M').to_i
123
+ hours = t.strftime('%H').to_i
124
+ days = (t.strftime('%j').to_i)-1
125
+ years = (t.strftime('%Y').to_i) - (Time.at(0).gmtime.strftime('%Y').to_i)
126
+
127
+ stuff = []
128
+
129
+ stuff.push("#{seconds} Second#{'s' if seconds != 1}") if seconds > 0 or !minutes
130
+ stuff.push("#{minutes} Minute#{'s' if minutes != 1}") if minutes > 0
131
+ stuff.push("#{hours} Hour#{'s' if hours != 1}") if hours > 0
132
+ stuff.push("#{days} Day#{'s' if days != 1}") if days > 0
133
+ stuff.push("#{years} Year#{'s' if years != 1}") if years > 0
134
+
135
+ stuff.reverse!
136
+
137
+ result = stuff[0, precision].join(' ')
138
+
139
+ result = ' - '+result if negative
140
+
141
+ return result
142
+ end
143
+
144
+ #escape the string
145
+ def escape(string)
146
+ result = string.gsub('\\', '\\\\\\')
147
+ result.gsub!(';', '\\.')
148
+ return result
149
+ end
150
+
151
+ #unescape the string
152
+ def unescape(string)
153
+ result = string.gsub("\\.", "\\\\.")
154
+ result.gsub!(%r{\\{1}\\\.}, '!.')
155
+ result.gsub!('\\.', ';')
156
+ result.gsub!('!.', '\\.')
157
+ result.gsub!('\\\\', '\\')
158
+ return result
159
+ end
160
+
161
+ def escape_xml(string)
162
+ s = string.gsub('&', '&amp;')
163
+ s = s.gsub('<', '&lt;').gsub('>', '&gt;')
164
+ return s
165
+ end
166
+
167
+ def to_uri(uri)
168
+ if uri =~ /^[a-zA-Z]+\:\/\/.+/
169
+ return uri
170
+ else
171
+ return 'http://'+uri
172
+ end
173
+ end
174
+ class Object
175
+ def deep_clone
176
+ Marshal.load(Marshal.dump(self))
177
+ end
178
+ end