PerfectlyNormal-Flexo 0.4.0 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/flexo.gemspec +2 -2
- data/lib/flexo/constants.rb +1 -1
- data/lib/flexo/dispatcher.rb +7 -16
- data/lib/flexo/manager.rb +23 -17
- data/lib/flexo/plugin.rb +26 -4
- data/lib/flexo/pluginmanager.rb +13 -1
- data/lib/flexo/server.rb +48 -22
- data/lib/flexo/trigger.rb +4 -0
- data/plugins/auth.rb +21 -14
- data/plugins/control.rb +36 -8
- data/plugins/pstore.rb +12 -6
- metadata +2 -2
data/flexo.gemspec
CHANGED
data/lib/flexo/constants.rb
CHANGED
data/lib/flexo/dispatcher.rb
CHANGED
@@ -96,24 +96,14 @@ module Flexo
|
|
96
96
|
end
|
97
97
|
|
98
98
|
# Removes an event handler.
|
99
|
-
# Known to be broken.
|
100
|
-
# DO NOT USE.
|
101
|
-
# See bug #28
|
102
99
|
def unsubscribe(handler)
|
103
100
|
@manager.logger.debug("Going to remove handler #{handler}")
|
104
|
-
|
105
|
-
@
|
106
|
-
|
107
|
-
if handlers.delete(handler)
|
108
|
-
events << e
|
109
|
-
@manager.logger.debug("Adding #{e} to removal queue")
|
110
|
-
end
|
111
|
-
}
|
112
|
-
events.each { |e|
|
113
|
-
@manager.logger.debug("Removing #{e}")
|
114
|
-
@handlers.delete(e)
|
115
|
-
}
|
101
|
+
|
102
|
+
@handlers.each do |event,handlers|
|
103
|
+
handlers.delete handler
|
116
104
|
end
|
105
|
+
|
106
|
+
@manager.logger.debug("Handler #{handler} removed")
|
117
107
|
end
|
118
108
|
|
119
109
|
# Easy way to add a trigger.
|
@@ -121,7 +111,8 @@ module Flexo
|
|
121
111
|
def add_trigger(pattern, &block)
|
122
112
|
trigger = Flexo::Trigger.new(pattern, &block)
|
123
113
|
@manager.mutex { @triggers << trigger }
|
124
|
-
|
114
|
+
|
115
|
+
return trigger
|
125
116
|
end
|
126
117
|
|
127
118
|
# Easy way to remove a trigger.
|
data/lib/flexo/manager.rb
CHANGED
@@ -55,8 +55,11 @@ module Flexo
|
|
55
55
|
|
56
56
|
@logger.debug "Creating PluginManager"
|
57
57
|
@pluginmanager = Flexo::PluginManager.new(@pluginmutex)
|
58
|
-
|
59
|
-
@
|
58
|
+
|
59
|
+
@config['plugin.autoload'] ||= []
|
60
|
+
@config['plugin.autoload'].each do |plugin|
|
61
|
+
@pluginmanager.load_plugin(plugin)
|
62
|
+
end
|
60
63
|
|
61
64
|
@logger.debug "Creating Sender"
|
62
65
|
@sender = Flexo::Sender.new
|
@@ -80,21 +83,16 @@ module Flexo
|
|
80
83
|
@logger.info "Setting up default handlers"
|
81
84
|
dispatcher.subscribe(:PING) { |ping| ping.pong }
|
82
85
|
dispatcher.subscribe(Flexo::Events::PrivmsgEvent) { |msg|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
@sender.notice(msg.data.hostmask.nickname, cmd)
|
94
|
-
when 'QUIT'
|
95
|
-
if msg.text.split(' ')[1] == 'lololz'
|
96
|
-
@server.disconnect
|
97
|
-
exit
|
86
|
+
if msg.ctcp?
|
87
|
+
case msg.text.split(' ')[0].upcase
|
88
|
+
when 'VERSION'
|
89
|
+
l = "\001VERSION Flexo #{Flexo::Constants::FLEXO_VERSION} "
|
90
|
+
l += "(#{Flexo::Constants::FLEXO_RELEASE})\001"
|
91
|
+
@sender.notice(msg.data.hostmask.nickname, l)
|
92
|
+
when 'PING'
|
93
|
+
arg = msg.text.split(' ')[1]
|
94
|
+
cmd = "\001PING #{arg}\001"
|
95
|
+
@sender.notice(msg.data.hostmask.nickname, cmd)
|
98
96
|
end
|
99
97
|
end
|
100
98
|
}
|
@@ -146,9 +144,17 @@ module Flexo
|
|
146
144
|
return @server
|
147
145
|
end
|
148
146
|
|
147
|
+
def plugin
|
148
|
+
return @pluginmanager
|
149
|
+
end
|
150
|
+
|
149
151
|
def load_plugin(plugin)
|
150
152
|
return @pluginmanager.load_plugin(plugin)
|
151
153
|
end
|
154
|
+
|
155
|
+
def find_plugins
|
156
|
+
return @pluginmanager.find_plugins
|
157
|
+
end
|
152
158
|
|
153
159
|
def nickname; return @nickname; end
|
154
160
|
def nickname=(nick); @nickname = nick; nick; end
|
data/lib/flexo/plugin.rb
CHANGED
@@ -18,10 +18,31 @@ module Flexo
|
|
18
18
|
|
19
19
|
# Variable, mutex, check.
|
20
20
|
def initialize(plugins, *args)
|
21
|
-
@manager
|
22
|
-
@plugins
|
21
|
+
@manager = Flexo::Manager.instance
|
22
|
+
@plugins = plugins
|
23
|
+
@triggers = []
|
24
|
+
@handlers = []
|
23
25
|
@manager.logger.debug "Created #{self.class}, with #{@plugins.to_a}"
|
24
26
|
end
|
27
|
+
|
28
|
+
# Unloading a plugin. This default action unsubscribes all triggers
|
29
|
+
# and handlers, so nothing goes wrong when the plugin is unloaded and
|
30
|
+
# the dispatcher still tries to run their blocks
|
31
|
+
def unload
|
32
|
+
@manager.logger.debug "Plugin: Unloading"
|
33
|
+
@manager.logger.debug " has #{@triggers.length} triggers"
|
34
|
+
@manager.logger.debug " and #{@handlers.length} handlers"
|
35
|
+
|
36
|
+
@triggers.each do |trigger|
|
37
|
+
@manager.logger.debug " Removing trigger #{trigger}"
|
38
|
+
remove_trigger trigger
|
39
|
+
end
|
40
|
+
|
41
|
+
@handlers.each do |handler|
|
42
|
+
@manager.logger.debug " Removing handler #{handler}"
|
43
|
+
unsubscribe handler
|
44
|
+
end
|
45
|
+
end
|
25
46
|
|
26
47
|
# Overriding method_missing to let plugins use commands
|
27
48
|
# from other plugins. If the plugin tries to use a function
|
@@ -48,7 +69,7 @@ module Flexo
|
|
48
69
|
|
49
70
|
# Convenience. See Flexo::Dispatcher.subscribe
|
50
71
|
def subscribe(event, &block)
|
51
|
-
@manager.dispatcher.subscribe(event, &block)
|
72
|
+
mutex { @handlers << @manager.dispatcher.subscribe(event, &block) }
|
52
73
|
end
|
53
74
|
|
54
75
|
# Convenience. See Flexo::Dispatcher.unsubscribe
|
@@ -58,7 +79,8 @@ module Flexo
|
|
58
79
|
|
59
80
|
# Convenience. See Flexo::Dispatcher.add_trigger
|
60
81
|
def add_trigger(pattern, &block)
|
61
|
-
@manager.
|
82
|
+
@manager.logger.debug("Adding a trigger against #{pattern}")
|
83
|
+
mutex { @triggers << @manager.dispatcher.add_trigger(pattern, &block) }
|
62
84
|
end
|
63
85
|
|
64
86
|
# Convenience. See Flexo::Dispatcher.remove_trigger
|
data/lib/flexo/pluginmanager.rb
CHANGED
@@ -5,6 +5,9 @@ module Flexo
|
|
5
5
|
# Here's the interesting parts. This class is responsible for...
|
6
6
|
# Managing plugins! Who would've thought that...
|
7
7
|
class PluginManager
|
8
|
+
attr_reader :plugins_loaded
|
9
|
+
attr_reader :plugins_available
|
10
|
+
|
8
11
|
# As usual. Set up some things. Create some arrays, some hashes,
|
9
12
|
# get a mutex. All that
|
10
13
|
def initialize(mutex)
|
@@ -44,6 +47,7 @@ module Flexo
|
|
44
47
|
"The plugin name #{klass::NAME} is already being used by another plugin."
|
45
48
|
end
|
46
49
|
@plugins_available << klass
|
50
|
+
@plugins_available.uniq!
|
47
51
|
end
|
48
52
|
end
|
49
53
|
end
|
@@ -99,8 +103,16 @@ module Flexo
|
|
99
103
|
@manager.logger.debug " Already loaded #{klass.class}"
|
100
104
|
plugin = @plugins_loaded[klass::NAME]
|
101
105
|
end
|
102
|
-
|
106
|
+
|
103
107
|
plugin
|
104
108
|
end
|
109
|
+
|
110
|
+
# Unloads a plugin
|
111
|
+
def unload_plugin(plugin)
|
112
|
+
@manager.logger.debug "Going to unload plugin #{plugin}"
|
113
|
+
klass = @plugins_loaded[plugin]
|
114
|
+
@manager.mutex { @plugins_loaded.delete(plugin) }
|
115
|
+
klass.unload
|
116
|
+
end
|
105
117
|
end
|
106
118
|
end
|
data/lib/flexo/server.rb
CHANGED
@@ -10,13 +10,11 @@ module Flexo
|
|
10
10
|
attr_reader :thread
|
11
11
|
attr_reader :server
|
12
12
|
attr_reader :nickname
|
13
|
-
attr_reader :monitor
|
14
13
|
|
15
14
|
def initialize
|
16
15
|
@manager = Flexo::Manager.instance
|
17
16
|
@socket = nil
|
18
17
|
@server = nil
|
19
|
-
@monitor = nil
|
20
18
|
end
|
21
19
|
|
22
20
|
def setup
|
@@ -29,17 +27,11 @@ module Flexo
|
|
29
27
|
end
|
30
28
|
disconnect
|
31
29
|
rescue Errno::ETIMEDOUT
|
32
|
-
@manager.logger.
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
# Set up a thread to check the connection once
|
38
|
-
# in a while. See bug #15
|
39
|
-
@monitor = Thread.new do
|
40
|
-
while true
|
41
|
-
sleep 45
|
42
|
-
check_connection
|
30
|
+
@manager.logger.error "Connection lost. Reconnecting"
|
31
|
+
reconnect
|
32
|
+
rescue Errno::ECONNRESET
|
33
|
+
@manager.logger.error "Connection reset by peer. Reconnecting after five seconds"
|
34
|
+
reconnect 5
|
43
35
|
end
|
44
36
|
end
|
45
37
|
end
|
@@ -51,19 +43,49 @@ module Flexo
|
|
51
43
|
# Called by Sender.quote. This function just writes the
|
52
44
|
# prepared line to the socket.
|
53
45
|
def quote(data)
|
54
|
-
|
46
|
+
begin
|
47
|
+
@socket.print("#{data.chomp}\r\n")
|
48
|
+
@socket.flush
|
49
|
+
rescue IOError => e
|
50
|
+
@manager.logger.error("Connection to #{@server} lost")
|
51
|
+
disconnect
|
52
|
+
exit 1
|
53
|
+
end
|
55
54
|
end
|
56
55
|
|
57
56
|
# Does the connecting, looping through the defined
|
58
57
|
# servers, trying the next one if it fails.
|
59
58
|
def connect
|
60
59
|
debug "Starting to connect!"
|
60
|
+
host = @manager.config['core.hostname'].to_s
|
61
61
|
@manager.config['core.server'].each do |server|
|
62
62
|
debug "Connecting to #{server[:host]}:#{server[:port]}"
|
63
|
+
debug " using host #{host}" if host.length > 0
|
64
|
+
debug " using SSL" if server[:ssl]
|
63
65
|
timeout(30) do
|
64
66
|
err = 0
|
65
67
|
begin
|
66
|
-
|
68
|
+
if host.length > 0
|
69
|
+
@socket = TCPSocket.new(server[:host], server[:port], host)
|
70
|
+
else
|
71
|
+
@socket = TCPSocket.new(server[:host], server[:port])
|
72
|
+
end
|
73
|
+
|
74
|
+
if(server[:ssl])
|
75
|
+
begin
|
76
|
+
require 'openssl'
|
77
|
+
rescue LoadError
|
78
|
+
@manager.logger.error "SSL library not available."
|
79
|
+
continue
|
80
|
+
end
|
81
|
+
|
82
|
+
context = OpenSSL::SSL::SSLContext.new()
|
83
|
+
# FIXME: Might want to change this one, or at least have it configurable
|
84
|
+
context.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
85
|
+
@socket = OpenSSL::SSL::SSLSocket.new(@socket, context)
|
86
|
+
@socket.sync_close = true
|
87
|
+
@socket.connect
|
88
|
+
end
|
67
89
|
rescue Errno::ECONNREFUSED => h
|
68
90
|
msg = "Connection to #{server[:host]} at port #{server[:port]} was refused"
|
69
91
|
err = 1
|
@@ -76,6 +98,9 @@ module Flexo
|
|
76
98
|
rescue Errno::EADDRNOTAVAIL => h
|
77
99
|
msg = "Unable to assign requested address"
|
78
100
|
err = 2
|
101
|
+
rescue OpenSSL::SSL::SSLError => h
|
102
|
+
msg = "Unable to connect using SSL (#{h.message})"
|
103
|
+
err = 1
|
79
104
|
end
|
80
105
|
|
81
106
|
if(err != 0)
|
@@ -87,6 +112,7 @@ module Flexo
|
|
87
112
|
end
|
88
113
|
else
|
89
114
|
@manager.logger.info("Connected to #{server[:host]}")
|
115
|
+
@server = server[:host]
|
90
116
|
login
|
91
117
|
return
|
92
118
|
end
|
@@ -94,13 +120,6 @@ module Flexo
|
|
94
120
|
end
|
95
121
|
end
|
96
122
|
|
97
|
-
def check_connection
|
98
|
-
if(@socket == nil || @socket.closed?)
|
99
|
-
@manager.logger.error("Not connected to a server. Trying again.")
|
100
|
-
connect
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
123
|
# This function goes through the login-process
|
105
124
|
def login
|
106
125
|
config = @manager.config
|
@@ -126,5 +145,12 @@ module Flexo
|
|
126
145
|
def disconnect
|
127
146
|
@socket.close unless @socket.closed?
|
128
147
|
end
|
148
|
+
|
149
|
+
# Reconnects
|
150
|
+
def reconnect(s = 0)
|
151
|
+
disconnect
|
152
|
+
sleep s
|
153
|
+
connect
|
154
|
+
end
|
129
155
|
end
|
130
156
|
end
|
data/lib/flexo/trigger.rb
CHANGED
data/plugins/auth.rb
CHANGED
@@ -10,7 +10,7 @@ module Flexo
|
|
10
10
|
# executes.
|
11
11
|
class AuthPlugin < Flexo::Plugin
|
12
12
|
NAME = 'auth'
|
13
|
-
VERSION = '0.1.
|
13
|
+
VERSION = '0.1.4'
|
14
14
|
SUMMARY = 'Access control list for managing users and their permissions.'
|
15
15
|
DEPENDS = ['pstore', 'ruby-digest/md5']
|
16
16
|
|
@@ -28,8 +28,8 @@ module Flexo
|
|
28
28
|
add_restricted_trigger(/^user remove ([a-zA-Z][a-zA-Z0-9_-]*)$/, :level => 256, &method(:cmd_remove))
|
29
29
|
add_trigger(/^user lookup ([a-zA-Z][a-zA-Z0-9_-]*)$/, &method(:cmd_lookup))
|
30
30
|
|
31
|
-
pstore_open("#{@manager.config.path}/user.db")
|
32
|
-
|
31
|
+
@db = pstore_open("#{@manager.config.path}/user.db")
|
32
|
+
@db.transaction do |pstore|
|
33
33
|
pstore[:users] ||= Hash.new
|
34
34
|
end
|
35
35
|
end
|
@@ -37,7 +37,7 @@ module Flexo
|
|
37
37
|
# Returns the number of users currently registered
|
38
38
|
# in the database.
|
39
39
|
def usercount
|
40
|
-
|
40
|
+
@db.transaction do |pstore|
|
41
41
|
return pstore[:users].length
|
42
42
|
end
|
43
43
|
end
|
@@ -47,6 +47,7 @@ module Flexo
|
|
47
47
|
# whether the user is allowed to run the command or not.
|
48
48
|
def add_restricted_trigger(pattern, opts = {}, &block)
|
49
49
|
opts = { :level => 0 }.merge(opts)
|
50
|
+
@manager.logger.debug("Adding restricted trigger against #{pattern}")
|
50
51
|
add_trigger(pattern) do |privmsg,*args|
|
51
52
|
@manager.logger.debug "Trying to run a restricted method"
|
52
53
|
level = opts[:level].to_i
|
@@ -63,6 +64,12 @@ module Flexo
|
|
63
64
|
block.call(privmsg,*args)
|
64
65
|
end
|
65
66
|
end
|
67
|
+
|
68
|
+
# Plenty of plugins use this method, and their trigger
|
69
|
+
# gets added to this class's triggers. Therefore
|
70
|
+
# we pop it, and return it, leaving it up to the plugin to
|
71
|
+
# keep track of those
|
72
|
+
return @triggers.pop
|
66
73
|
end
|
67
74
|
|
68
75
|
# Finds a user in the database
|
@@ -71,7 +78,7 @@ module Flexo
|
|
71
78
|
@manager.logger.debug "AuthPlugin: Trying to find #{nick}"
|
72
79
|
user = nil
|
73
80
|
|
74
|
-
|
81
|
+
@db.transaction do |pstore|
|
75
82
|
user = pstore[:users].find do |name,user|
|
76
83
|
user[:hostmasks].any? do |dbnick,dbhost|
|
77
84
|
dbnick.downcase == nick.downcase &&\
|
@@ -95,7 +102,7 @@ module Flexo
|
|
95
102
|
def username_exists?(username)
|
96
103
|
found = false
|
97
104
|
@manager.logger.debug "Going to see if #{username} exists"
|
98
|
-
|
105
|
+
@db.transaction do |pstore|
|
99
106
|
pstore[:users].keys.any? { |dbname|
|
100
107
|
@manager.logger.debug " Checking #{dbname} against #{username}"
|
101
108
|
found = (dbname.downcase == username.downcase)
|
@@ -111,7 +118,7 @@ module Flexo
|
|
111
118
|
@manager.logger.debug "Auth: Host: Checking if #{nick} and #{mask} exists"
|
112
119
|
found = false
|
113
120
|
|
114
|
-
|
121
|
+
@db.transaction do |pstore|
|
115
122
|
pstore[:users].any? do |name,user|
|
116
123
|
user[:hostmasks].any? do |dbnick,dbmask|
|
117
124
|
found = true if (dbnick.downcase == nick.downcase && dbmask.downcase == mask.downcase)
|
@@ -126,7 +133,7 @@ module Flexo
|
|
126
133
|
# Returns true if the username/password combination
|
127
134
|
# matches, and false if it does not.
|
128
135
|
def is_correct?(user, pass)
|
129
|
-
c =
|
136
|
+
c = @db.transaction do |pstore|
|
130
137
|
pstore[:users][user.downcase][:password] == Digest::MD5.hexdigest(pass).to_s
|
131
138
|
end
|
132
139
|
|
@@ -145,14 +152,14 @@ module Flexo
|
|
145
152
|
:level => level.to_i
|
146
153
|
}
|
147
154
|
|
148
|
-
|
155
|
+
@db.transaction do |pstore|
|
149
156
|
pstore[:users][user] = tmpuser
|
150
157
|
end
|
151
158
|
end
|
152
159
|
|
153
160
|
# Adds a nickname/hostmask combo to a given user
|
154
161
|
def addmask(user, nick, mask)
|
155
|
-
|
162
|
+
@db.transaction do |pstore|
|
156
163
|
pstore[:users][user.downcase][:hostmasks] << [nick, mask]
|
157
164
|
end
|
158
165
|
end
|
@@ -189,7 +196,7 @@ module Flexo
|
|
189
196
|
def cmd_changelevel(privmsg, username, level)
|
190
197
|
return notify_user_not_found(privmsg) if !username_exists?(username)
|
191
198
|
|
192
|
-
|
199
|
+
@db.transaction do |pstore|
|
193
200
|
pstore[:users][username.downcase][:level] = level.to_i
|
194
201
|
end
|
195
202
|
|
@@ -201,7 +208,7 @@ module Flexo
|
|
201
208
|
@manager.logger.debug "AuthPlugin: Going to remove #{username}"
|
202
209
|
return notify_user_not_found(privmsg) if !username_exists?(username)
|
203
210
|
|
204
|
-
|
211
|
+
@db.transaction do |pstore|
|
205
212
|
pstore[:users].delete(username.downcase)
|
206
213
|
end
|
207
214
|
|
@@ -219,7 +226,7 @@ module Flexo
|
|
219
226
|
|
220
227
|
level = 0
|
221
228
|
|
222
|
-
|
229
|
+
@db.transaction do |pstore|
|
223
230
|
level = pstore[:users][username.downcase][:level]
|
224
231
|
end
|
225
232
|
|
@@ -253,4 +260,4 @@ module Flexo
|
|
253
260
|
end
|
254
261
|
end
|
255
262
|
end
|
256
|
-
end
|
263
|
+
end
|
data/plugins/control.rb
CHANGED
@@ -14,11 +14,13 @@ module Flexo
|
|
14
14
|
super
|
15
15
|
|
16
16
|
@manager.logger.debug("ControlPlugin started")
|
17
|
-
add_restricted_trigger(/^ctrl quit ?(.+)*$/, :level => 256, &method(:cmd_quit))
|
18
|
-
add_restricted_trigger(/^ctrl join (#\S+)$/, :level => 192, &method(:cmd_join))
|
19
|
-
add_restricted_trigger(/^ctrl part (#\S+)$/, :level => 192, &method(:cmd_part))
|
20
|
-
add_restricted_trigger(/^ctrl plugin load (\S+)$/, :level => 256, &method(:cmd_loadplugin))
|
21
|
-
add_restricted_trigger(/^ctrl plugin unload (\S+)$/, :level => 256, &method(:cmd_unloadplugin))
|
17
|
+
@triggers << add_restricted_trigger(/^ctrl quit ?(.+)*$/, :level => 256, &method(:cmd_quit))
|
18
|
+
@triggers << add_restricted_trigger(/^ctrl join (#\S+)$/, :level => 192, &method(:cmd_join))
|
19
|
+
@triggers << add_restricted_trigger(/^ctrl part (#\S+)$/, :level => 192, &method(:cmd_part))
|
20
|
+
@triggers << add_restricted_trigger(/^ctrl plugin load (\S+)$/, :level => 256, &method(:cmd_loadplugin))
|
21
|
+
@triggers << add_restricted_trigger(/^ctrl plugin unload (\S+)$/, :level => 256, &method(:cmd_unloadplugin))
|
22
|
+
@triggers << add_restricted_trigger(/^ctrl plugin find$/, :level => 256, &method(:cmd_findplugins))
|
23
|
+
add_trigger(/^ctrl plugin list$/, &method(:cmd_listplugin))
|
22
24
|
end
|
23
25
|
|
24
26
|
private
|
@@ -31,7 +33,8 @@ module Flexo
|
|
31
33
|
@manager.sender.part(channel)
|
32
34
|
end
|
33
35
|
|
34
|
-
def cmd_quit(privmsg, message
|
36
|
+
def cmd_quit(privmsg, message)
|
37
|
+
message ||= "Leaving!"
|
35
38
|
@manager.logger.info("Requested to quit...")
|
36
39
|
@manager.sender.quit(message)
|
37
40
|
end
|
@@ -46,8 +49,33 @@ module Flexo
|
|
46
49
|
end
|
47
50
|
|
48
51
|
def cmd_unloadplugin(privmsg, plugin)
|
49
|
-
|
52
|
+
loaded = @manager.plugin.plugins_loaded
|
53
|
+
|
54
|
+
if(!loaded.include?(plugin))
|
55
|
+
privmsg.reply "The plugin #{plugin} is not loaded"
|
56
|
+
else
|
57
|
+
@manager.plugin.unload_plugin(plugin)
|
58
|
+
privmsg.reply "Successfully unloaded #{plugin}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def cmd_listplugin(privmsg)
|
63
|
+
loaded = @manager.plugin.plugins_loaded
|
64
|
+
available = @manager.plugin.plugins_available
|
65
|
+
|
66
|
+
available.each do |plug|
|
67
|
+
str = "#{plug::NAME} (#{plug::VERSION}"
|
68
|
+
str += ", loaded" if loaded.include?(plug::NAME)
|
69
|
+
str += ") - #{plug::SUMMARY}"
|
70
|
+
|
71
|
+
privmsg.reply str
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def cmd_findplugins(privmsg)
|
76
|
+
@manager.find_plugins
|
77
|
+
privmsg.reply "Reloaded list of plugins"
|
50
78
|
end
|
51
79
|
end
|
52
80
|
end
|
53
|
-
end
|
81
|
+
end
|
data/plugins/pstore.rb
CHANGED
@@ -2,31 +2,37 @@ module Flexo
|
|
2
2
|
module Plugins
|
3
3
|
class PStorePlugin < Flexo::Plugin
|
4
4
|
NAME = 'pstore'
|
5
|
-
VERSION = '0.1.
|
5
|
+
VERSION = '0.1.3'
|
6
6
|
SUMMARY = 'A plugin that provides permanent storage for other plugins'
|
7
7
|
DEPENDS = ['ruby-pstore']
|
8
8
|
|
9
9
|
def initialize(*args)
|
10
10
|
super
|
11
|
-
@pstore = nil
|
12
11
|
@manager = Flexo::Manager.instance
|
13
12
|
end
|
14
13
|
|
15
14
|
# Opens a database.
|
16
15
|
def pstore_open(file)
|
17
16
|
begin
|
18
|
-
|
17
|
+
return PStoreWrapper.new(file)
|
19
18
|
rescue
|
20
19
|
raise PluginError("PStore: Unable to open database")
|
21
20
|
end
|
22
21
|
end
|
23
|
-
|
22
|
+
end
|
23
|
+
|
24
|
+
class PStoreWrapper
|
25
|
+
def initialize(file)
|
26
|
+
@manager = Flexo::Manager.instance
|
27
|
+
@pstore = PStore.new(file)
|
28
|
+
end
|
29
|
+
|
24
30
|
# Convenience function for utilizing the mutex, creating
|
25
31
|
# a transaction on our PStore-object, and running a code
|
26
32
|
# block against it.
|
27
|
-
def
|
33
|
+
def transaction(&block)
|
28
34
|
@manager.logger.debug "PStore: Starting transaction"
|
29
|
-
|
35
|
+
@manager.pluginmutex { @pstore.transaction(&block) }
|
30
36
|
@manager.logger.debug "PStore: Transaction complete"
|
31
37
|
end
|
32
38
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: PerfectlyNormal-Flexo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Per Christian B. Viken
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-10-
|
12
|
+
date: 2008-10-19 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|