butler 1.8.2 → 1.8.3
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/Rakefile +1 -1
- data/bin/botcontrol +1 -1
- data/data/butler/dialogs/create_config.rb +2 -2
- data/data/butler/dialogs/quickcreate.rb +6 -4
- data/data/butler/dialogs/uninstall.rb +4 -3
- data/data/butler/plugins/core/access.rb +10 -10
- data/data/butler/plugins/dev/bleakhouse.rb +19 -8
- data/data/butler/plugins/operator/deop.rb +10 -1
- data/data/butler/plugins/operator/devoice.rb +9 -0
- data/data/butler/plugins/operator/limit.rb +12 -0
- data/data/butler/plugins/operator/op.rb +9 -0
- data/data/butler/plugins/operator/voice.rb +10 -0
- data/data/butler/plugins/util/calculator.rb +11 -0
- data/data/butler/services/org.rubyforge.butler/calculator/1/calculator.rb +68 -0
- data/data/butler/services/org.rubyforge.butler/log/1/service.rb +198 -0
- data/data/butler/services/org.rubyforge.butler/strings/1/data/en/acknowledge.yaml +8 -0
- data/data/butler/services/org.rubyforge.butler/strings/1/data/en/gratitude.yaml +3 -0
- data/data/butler/services/org.rubyforge.butler/strings/1/data/en/hello.yaml +6 -0
- data/data/butler/services/org.rubyforge.butler/strings/1/data/en/ignorance.yaml +7 -0
- data/data/butler/services/org.rubyforge.butler/strings/1/data/en/ignorance_about.yaml +3 -0
- data/data/butler/services/org.rubyforge.butler/strings/1/data/en/insult.yaml +3 -0
- data/data/butler/services/org.rubyforge.butler/strings/1/data/en/rejection.yaml +12 -0
- data/data/butler/services/org.rubyforge.butler/strings/1/service.rb +50 -0
- data/lib/access.rb +6 -3
- data/lib/access/privilege.rb +9 -78
- data/lib/access/privilegelist.rb +75 -0
- data/lib/access/role.rb +14 -94
- data/lib/access/role/base.rb +40 -0
- data/lib/access/rolelist.rb +99 -0
- data/lib/access/savable.rb +6 -3
- data/lib/access/user.rb +21 -19
- data/lib/access/version.rb +17 -0
- data/lib/access/yamlbase.rb +64 -48
- data/lib/butler.rb +1 -0
- data/lib/butler/bot.rb +8 -2
- data/lib/butler/control.rb +3 -1
- data/lib/butler/initialvalues.rb +1 -1
- data/lib/butler/irc/client.rb +6 -0
- data/lib/butler/irc/message.rb +14 -9
- data/lib/butler/irc/parser.rb +8 -5
- data/lib/butler/irc/parser/generic.rb +33 -1
- data/lib/butler/irc/parser/rfc2812.rb +5 -2
- data/lib/butler/plugin.rb +22 -2
- data/lib/butler/plugins.rb +2 -7
- data/lib/butler/service.rb +73 -0
- data/lib/butler/services.rb +65 -0
- data/lib/butler/version.rb +1 -1
- data/lib/ruby/array/random.rb +17 -0
- data/lib/ruby/string/camelcase.rb +14 -0
- data/test/test_access.rb +164 -59
- data/test/test_access/privilege/banners.statistics.yaml +3 -0
- data/test/test_access/privilege/banners.yaml +3 -0
- data/test/test_access/privilege/news.create.yaml +3 -0
- data/test/test_access/privilege/news.delete.yaml +3 -0
- data/test/test_access/privilege/news.edit.yaml +3 -0
- data/test/test_access/privilege/news.read.yaml +3 -0
- data/test/test_access/privilege/news.yaml +3 -0
- data/test/test_access/privilege/paid_content.yaml +3 -0
- data/test/test_access/privilege/statistics.ftp.yaml +3 -0
- data/test/test_access/privilege/statistics.web.yaml +3 -0
- data/test/test_access/privilege/statistics.yaml +3 -0
- data/test/test_access/role/chiefeditor.yaml +7 -0
- data/test/test_access/role/editor.yaml +9 -0
- data/test/test_access/user/test.yaml +12 -0
- metadata +51 -5
- data/data/butler/plugins/core/user.rb +0 -166
- data/data/butler/plugins/dev/onhandlers.rb +0 -93
- data/data/butler/plugins/service/log.rb +0 -183
@@ -1,166 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright 2007 by Stefan Rusterholz.
|
3
|
-
# All rights reserved.
|
4
|
-
# See LICENSE.txt for permissions.
|
5
|
-
#++
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
trigger "user"
|
10
|
-
|
11
|
-
def on_trigger
|
12
|
-
case arguments(1)
|
13
|
-
when "create"
|
14
|
-
name, pass, active = @message.arguments[2,3]
|
15
|
-
active = active && !%(false off).include?(active.downcase)
|
16
|
-
return answer(usage) unless name and pass
|
17
|
-
if @butler.access.user.exists?(name) then
|
18
|
-
answer(:exists, :name => name)
|
19
|
-
else
|
20
|
-
@butler.access.user.create(name, pass, nil, false, :active => active)
|
21
|
-
answer(:created, :name => name)
|
22
|
-
end
|
23
|
-
|
24
|
-
when "delete"
|
25
|
-
return answer(usage) unless name = @message.arguments[2]
|
26
|
-
if @butler.access.user.exists?(name) then
|
27
|
-
@butler.access.user.delete(name)
|
28
|
-
answer(:deleted)
|
29
|
-
else
|
30
|
-
answer(:doesnt_exist, :name => name)
|
31
|
-
end
|
32
|
-
|
33
|
-
when "activate"
|
34
|
-
return answer(usage) unless name = @message.arguments[2]
|
35
|
-
if @butler.access.user.exists?(name) then
|
36
|
-
@butler.access.user[name].activate
|
37
|
-
answer(:activated)
|
38
|
-
else
|
39
|
-
answer(:doesnt_exist, :name => name)
|
40
|
-
end
|
41
|
-
|
42
|
-
when "deactivate"
|
43
|
-
return answer(usage) unless name = @message.arguments[2]
|
44
|
-
if @butler.access.user.exists?(name) then
|
45
|
-
@butler.access.user[name].deactivate
|
46
|
-
answer(:deactivated)
|
47
|
-
else
|
48
|
-
answer(:doesnt_exist, :name => name)
|
49
|
-
end
|
50
|
-
|
51
|
-
when "list"
|
52
|
-
answer(:users, :names => @butler.access.user.keys.columnize(5))
|
53
|
-
|
54
|
-
when "privileges"
|
55
|
-
return answer(usage) unless name = @message.arguments[2]
|
56
|
-
return answer(:doesnt_exist, :name => name) unless user = @butler.access.user[name]
|
57
|
-
answer(:privileges, :name => name, :privileges => user.privileges.list.keys.columnize(5))
|
58
|
-
|
59
|
-
when "roles"
|
60
|
-
return answer(usage) unless name = @message.arguments[2]
|
61
|
-
return answer(:doesnt_exist, :name => name) unless user = @butler.access.user[name]
|
62
|
-
answer(:roles, :name => name, :roles => user.roles.map { |r| r.id }.columnize(5))
|
63
|
-
|
64
|
-
when "add"
|
65
|
-
return answer(usage) unless name = @message.arguments[3] and @message.arguments[4]
|
66
|
-
return answer(:doesnt_exist, :name => name) unless user = @butler.access.user[name]
|
67
|
-
case arguments(2)
|
68
|
-
when "privilege"
|
69
|
-
user.privileges.add(@message.arguments[4])
|
70
|
-
answer(:added_privilege, :name => name, :privilege => @message.arguments[4])
|
71
|
-
|
72
|
-
when "role"
|
73
|
-
role_name = @message.arguments[4]
|
74
|
-
answer(:role_doesnt_exist, :role => role_name) unless role = @butler.access.role[role_name]
|
75
|
-
user.roles.add(role)
|
76
|
-
answer(:added_role, :name => name, :role => role_name)
|
77
|
-
|
78
|
-
else
|
79
|
-
answer(usage)
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
when "remove"
|
84
|
-
return answer(usage) unless name = @message.arguments[3] and @message.arguments[4]
|
85
|
-
return answer(:doesnt_exist, :name => name) unless user = @butler.access.user[name]
|
86
|
-
case arguments(2)
|
87
|
-
when "privilege"
|
88
|
-
user.privileges.remove(@message.arguments[4])
|
89
|
-
answer(:removed_privilege, :name => name, :privilege => @message.arguments[4])
|
90
|
-
|
91
|
-
when "role"
|
92
|
-
role_name = @message.arguments[4]
|
93
|
-
answer(:role_doesnt_exist, :role => role_name) unless role = @butler.access.role[role_name]
|
94
|
-
user.roles.remove(role)
|
95
|
-
answer(:removed_role, :name => name, :role => role_name)
|
96
|
-
|
97
|
-
else
|
98
|
-
answer(usage)
|
99
|
-
|
100
|
-
end
|
101
|
-
|
102
|
-
else
|
103
|
-
answer(usage)
|
104
|
-
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
__END__
|
109
|
-
---
|
110
|
-
:revision:
|
111
|
-
:plugin: 1
|
112
|
-
:summary:
|
113
|
-
en: "Manage your users."
|
114
|
-
:about:
|
115
|
-
:mail: "apeiros@gmx.net"
|
116
|
-
:version: "1.0.0"
|
117
|
-
:author: "Stefan Rusterholz"
|
118
|
-
:strings:
|
119
|
-
:exists:
|
120
|
-
en: |
|
121
|
-
User <%= name %> exists already.
|
122
|
-
:doesnt_exist:
|
123
|
-
en: |
|
124
|
-
User <%= name %> does not exist.
|
125
|
-
:users:
|
126
|
-
en: |
|
127
|
-
Users:
|
128
|
-
<%= names %>
|
129
|
-
:privileges:
|
130
|
-
en: |
|
131
|
-
Privileges of <%= name %>:
|
132
|
-
<%= privileges %>
|
133
|
-
:roles:
|
134
|
-
en: |
|
135
|
-
Roles of <%= name %>:
|
136
|
-
<%= roles %>
|
137
|
-
:created:
|
138
|
-
en: |
|
139
|
-
Created user <%= name %>.
|
140
|
-
:deleted:
|
141
|
-
en: |
|
142
|
-
Deleted user <%= name %>.
|
143
|
-
:activated:
|
144
|
-
en: |
|
145
|
-
Activated user <%= name %>.
|
146
|
-
:deactivated:
|
147
|
-
en: |
|
148
|
-
Deactivated user <%= name %>.
|
149
|
-
:added_privilege:
|
150
|
-
en: |
|
151
|
-
Added privilege <%= privilege %> to <%= name %>.
|
152
|
-
:removed_privilege:
|
153
|
-
en: |
|
154
|
-
Removed privilege <%= privilege %> from <%= name %>.
|
155
|
-
:added_role:
|
156
|
-
en: |
|
157
|
-
Added role <%= role %> to <%= name %>.
|
158
|
-
:removed_role:
|
159
|
-
en: |
|
160
|
-
Removed role <%= role %> from <%= name %>.
|
161
|
-
:usage:
|
162
|
-
en: "![b]user![o] ('create' name password ['active' | 'inactive'] | ('delete' | 'activate' | 'deactivate') username | ('add' | 'remove') privilege)"
|
163
|
-
:help:
|
164
|
-
en:
|
165
|
-
"": |
|
166
|
-
Manage your users.
|
@@ -1,93 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright 2007 by Stefan Rusterholz.
|
3
|
-
# All rights reserved.
|
4
|
-
# See LICENSE.txt for permissions.
|
5
|
-
#++
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
extend OnHandlers
|
10
|
-
|
11
|
-
configuration(
|
12
|
-
"active" => false
|
13
|
-
)
|
14
|
-
|
15
|
-
trigger "onhandlers"
|
16
|
-
|
17
|
-
def on_trigger
|
18
|
-
if @message.arguments[1] && @message.arguments[1].downcase == "on" then
|
19
|
-
plugin.config["active"] = true
|
20
|
-
else
|
21
|
-
plugin.config["active"] = false
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def on_join(listener, user, channel)
|
26
|
-
debug("on_join triggered, #{user} joined #{channel}") if plugin.config["active"]
|
27
|
-
end
|
28
|
-
def on_privmsg(listener, user, text)
|
29
|
-
debug("on_privmsg triggered, #{user} wrote #{text}") if plugin.config["active"]
|
30
|
-
end
|
31
|
-
def on_notice(listener, user, text)
|
32
|
-
debug("on_notice triggered, #{user} wrote #{text}") if plugin.config["active"]
|
33
|
-
end
|
34
|
-
def on_nick(listener, user, old_nick)
|
35
|
-
debug("on_nick triggered, #{user} changed his nick from #{old_nick}") if plugin.config["active"]
|
36
|
-
end
|
37
|
-
def on_topic(listener, user, channel, topic)
|
38
|
-
debug("on_topic triggered, #{user} changed topic of #{channel} to #{topic}") if plugin.config["active"]
|
39
|
-
end
|
40
|
-
def on_part(listener, user, channel)
|
41
|
-
debug("on_part triggered, #{user} parted #{channel}") if plugin.config["active"]
|
42
|
-
end
|
43
|
-
def on_quit(listener, user, reason)
|
44
|
-
debug("on_quit triggered, #{user} has quit with #{reason}") if plugin.config["active"]
|
45
|
-
end
|
46
|
-
def on_kick(listener)
|
47
|
-
debug("on_kick triggered with #{@message}") if plugin.config["active"]
|
48
|
-
end
|
49
|
-
def on_kill(listener)
|
50
|
-
debug("on_kill triggered with #{@message}") if plugin.config["active"]
|
51
|
-
end
|
52
|
-
def on_kline(listener)
|
53
|
-
debug("on_kline triggered with #{@message}") if plugin.config["active"]
|
54
|
-
end
|
55
|
-
def on_invocation(listener)
|
56
|
-
debug("on_invocation triggered with #{@message}") if plugin.config["active"]
|
57
|
-
end
|
58
|
-
def on_ban(listener, *masks)
|
59
|
-
debug("on_ban triggered with #{@message}") if plugin.config["active"]
|
60
|
-
end
|
61
|
-
def on_unban(listener, *masks)
|
62
|
-
debug("on_unban triggered with #{@message}") if plugin.config["active"]
|
63
|
-
end
|
64
|
-
def on_op(listener, *users)
|
65
|
-
debug("on_op triggered with #{@message}") if plugin.config["active"]
|
66
|
-
end
|
67
|
-
def on_deop(listener, *users)
|
68
|
-
debug("on_deop triggered with #{@message}") if plugin.config["active"]
|
69
|
-
end
|
70
|
-
def on_voice(listener, *users)
|
71
|
-
debug("on_voice triggered with #{@message}") if plugin.config["active"]
|
72
|
-
end
|
73
|
-
def on_devoice(listener, *users)
|
74
|
-
debug("on_devoice triggered with #{@message}") if plugin.config["active"]
|
75
|
-
end
|
76
|
-
|
77
|
-
__END__
|
78
|
-
---
|
79
|
-
:revision:
|
80
|
-
:plugin: 1
|
81
|
-
:summary:
|
82
|
-
en: Testing all possible on_handlers
|
83
|
-
:about:
|
84
|
-
:mail: "apeiros@gmx.net"
|
85
|
-
:version: "1.0.0"
|
86
|
-
:author: "Stefan Rusterholz"
|
87
|
-
:strings:
|
88
|
-
:usage:
|
89
|
-
en: "This plugin does not offer a specific interface."
|
90
|
-
:help:
|
91
|
-
en:
|
92
|
-
"": |
|
93
|
-
This plugin is meant for diagnostic purposes only.
|
@@ -1,183 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright 2007 by Stefan Rusterholz.
|
3
|
-
# All rights reserved.
|
4
|
-
# See LICENSE.txt for permissions.
|
5
|
-
#++
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
require 'sequel/sqlite'
|
10
|
-
|
11
|
-
class <<self
|
12
|
-
attr_reader :log_db
|
13
|
-
attr_reader :log_table
|
14
|
-
end
|
15
|
-
|
16
|
-
@log_db = Sequel.sqlite @butler.path.log+'/log.sqlite'
|
17
|
-
|
18
|
-
configuration(
|
19
|
-
"channels" => []
|
20
|
-
)
|
21
|
-
@log_db.create_table(:log) {
|
22
|
-
primary_key :oid, :integer
|
23
|
-
int :time
|
24
|
-
str :channel, :size => 255
|
25
|
-
str :nick, :size => 48
|
26
|
-
int :type
|
27
|
-
text :text
|
28
|
-
} unless @log_db.table_exists?(:log)
|
29
|
-
@log_table = @log_db[:log]
|
30
|
-
|
31
|
-
MessageTypes = [:PRIVMSG, :NOTICE, :JOIN, :PART, :QUIT, :KICK, :KILL]
|
32
|
-
|
33
|
-
trigger "log"
|
34
|
-
|
35
|
-
def on_trigger
|
36
|
-
case @message.arguments[1]
|
37
|
-
when "list"
|
38
|
-
answer(:list, :channels => plugin.config["channels"])
|
39
|
-
when "on"
|
40
|
-
plugin.config["channels"] |= message.arguments[2..-1]
|
41
|
-
answer(:activated, :channels => message.arguments[2..-1])
|
42
|
-
when "off"
|
43
|
-
plugin.config["channels"] -= message.arguments[2..-1]
|
44
|
-
answer(:deactivated, :channels => message.arguments[2..-1])
|
45
|
-
when "search"
|
46
|
-
text, channel, from = @message.text.match(/search (.*)(?: in channel (#\w+))?(?: from (\w+))?$/).captures
|
47
|
-
text = "%#{text}%" if text
|
48
|
-
filtered = plugin.log_table #.filter { :type == 0 || :type == 1 }
|
49
|
-
filtered = filtered.filter { :nick == from } if from
|
50
|
-
filtered = filtered.filter { :nick == channel } if channel
|
51
|
-
filtered = filtered.filter { :text =~ text } if text
|
52
|
-
count = filtered.count
|
53
|
-
if count.zero? then
|
54
|
-
answer(:no_match)
|
55
|
-
else
|
56
|
-
upper = [5,count].min
|
57
|
-
answer("Found (1-#{upper} of #{count}):")
|
58
|
-
filtered.order(:time.DESC).first(5).each_with_index { |row, index|
|
59
|
-
answer(
|
60
|
-
"#{index+1}: " \
|
61
|
-
"[#{Time.at(row[:time]).strftime('%Y-%m-%d %H:%M')}, " \
|
62
|
-
"#{row[:from]} in #{row[:channel]}] " \
|
63
|
-
"#{row[:text]}"
|
64
|
-
)
|
65
|
-
}
|
66
|
-
end
|
67
|
-
when "dump"
|
68
|
-
n = @message.arguments[2].to_i
|
69
|
-
n = 5 if n.zero?
|
70
|
-
data = plugin.log_table.order(:time.DESC).first(n)
|
71
|
-
answer("Dump(#{data.length}):")
|
72
|
-
data.each_with_index { |row, index|
|
73
|
-
answer(
|
74
|
-
"#{index+1}: " \
|
75
|
-
"[#{Time.at(row[:time]).strftime('%Y-%m-%d %H:%M')}, " \
|
76
|
-
"#{row[:from]} in #{row[:channel]}] " \
|
77
|
-
"#{row[:text]}"
|
78
|
-
)
|
79
|
-
}
|
80
|
-
else
|
81
|
-
answer(usage)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
subscribe(:PRIVMSG, -10, nil, MessageTypes.index(:PRIVMSG)) { |listener, message, type|
|
86
|
-
next unless @config["channels"].include?(message.channel.to_str)
|
87
|
-
@log_table << {
|
88
|
-
:time => Time.now.to_i,
|
89
|
-
:channel => message.channel.to_str,
|
90
|
-
:nick => message.from.nick,
|
91
|
-
:type => type,
|
92
|
-
:text => message.text
|
93
|
-
}
|
94
|
-
}
|
95
|
-
subscribe(:NOTICE, -10, nil, MessageTypes.index(:NOTICE)) { |listener, message, type|
|
96
|
-
next unless @config["channels"].include?(message.channel.to_str)
|
97
|
-
@log_table << {
|
98
|
-
:time => Time.now.to_i,
|
99
|
-
:channel => message.channel.to_str,
|
100
|
-
:nick => message.from.nick,
|
101
|
-
:type => type,
|
102
|
-
:text => message.text
|
103
|
-
}
|
104
|
-
}
|
105
|
-
subscribe(:JOIN, -10, nil, MessageTypes.index(:JOIN)) { |listener, message, type|
|
106
|
-
next unless @config["channels"].include?(message.channel.to_str)
|
107
|
-
@log_table << {
|
108
|
-
:time => Time.now.to_i,
|
109
|
-
:channel => message.channel.to_str,
|
110
|
-
:nick => message.from.nick,
|
111
|
-
:type => type,
|
112
|
-
:text => nil
|
113
|
-
}
|
114
|
-
}
|
115
|
-
subscribe(:PART, -10, nil, MessageTypes.index(:PART)) { |listener, message, type|
|
116
|
-
next unless @config["channels"].include?(message.channel.to_str)
|
117
|
-
@log_table << {
|
118
|
-
:time => Time.now.to_i,
|
119
|
-
:channel => message.channel.to_str,
|
120
|
-
:nick => message.from.nick,
|
121
|
-
:type => type,
|
122
|
-
:text => message.text
|
123
|
-
}
|
124
|
-
}
|
125
|
-
subscribe(:QUIT, -10, nil, MessageTypes.index(:QUIT)) { |listener, message, type|
|
126
|
-
next unless @config["channels"].include?(message.channel.to_str)
|
127
|
-
@log_table << {
|
128
|
-
:time => Time.now.to_i,
|
129
|
-
:channel => message.channel.to_str,
|
130
|
-
:nick => message.from.nick,
|
131
|
-
:type => type,
|
132
|
-
:text => message.text
|
133
|
-
}
|
134
|
-
}
|
135
|
-
subscribe(:KICK, -10, nil, MessageTypes.index(:KICK)) { |listener, message, type|
|
136
|
-
next unless @config["channels"].include?(message.channel.to_str)
|
137
|
-
@log_table << {
|
138
|
-
:time => Time.now.to_i,
|
139
|
-
:channel => message.channel.to_str,
|
140
|
-
:nick => message.from.nick,
|
141
|
-
:type => type,
|
142
|
-
:text => message.text
|
143
|
-
}
|
144
|
-
}
|
145
|
-
subscribe(:KILL, -10, nil, MessageTypes.index(:KILL)) { |listener, message, type|
|
146
|
-
next unless @config["channels"].include?(message.channel.to_str)
|
147
|
-
@log_table << {
|
148
|
-
:time => Time.now.to_i,
|
149
|
-
:channel => message.channel.to_str,
|
150
|
-
:nick => message.from.nick,
|
151
|
-
:type => type,
|
152
|
-
:text => message.text
|
153
|
-
}
|
154
|
-
}
|
155
|
-
|
156
|
-
__END__
|
157
|
-
---
|
158
|
-
:revision:
|
159
|
-
:plugin: 1
|
160
|
-
:configuration: 1
|
161
|
-
:summary:
|
162
|
-
en: Log channel messages
|
163
|
-
:about:
|
164
|
-
:mail: "apeiros@gmx.net"
|
165
|
-
:version: "1.0.0"
|
166
|
-
:author: "Stefan Rusterholz"
|
167
|
-
:usage:
|
168
|
-
en: "![b]log![o] 'list'"
|
169
|
-
:help:
|
170
|
-
en:
|
171
|
-
"": Log channel messages.
|
172
|
-
:strings:
|
173
|
-
:no_match:
|
174
|
-
en: "No match found."
|
175
|
-
:list:
|
176
|
-
en: |
|
177
|
-
Logging is active for: <%= channels.join(', ') %>.
|
178
|
-
:activated:
|
179
|
-
en: |
|
180
|
-
Logging activated in: <%= channels.join(', ') %>.
|
181
|
-
:deactivated:
|
182
|
-
en: |
|
183
|
-
Logging deactivated in: <%= channels.join(', ') %>.
|