lita-locker 0.5.3 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +9 -14
- data/.travis.yml +1 -1
- data/CONTRIBUTING.md +9 -0
- data/Gemfile +1 -1
- data/lib/lita-locker.rb +10 -0
- data/lib/lita/handlers/locker.rb +62 -413
- data/lib/lita/handlers/locker_events.rb +41 -0
- data/lib/lita/handlers/locker_http.rb +30 -0
- data/lib/lita/handlers/locker_labels.rb +114 -0
- data/lib/lita/handlers/locker_misc.rb +62 -0
- data/lib/lita/handlers/locker_resources.rb +82 -0
- data/lib/locker/label.rb +67 -0
- data/lib/locker/misc.rb +15 -0
- data/lib/locker/regex.rb +12 -0
- data/lib/locker/resource.rb +48 -0
- data/lita-locker.gemspec +4 -4
- data/locales/en.yml +8 -1
- data/spec/lita/handlers/locker_events_spec.rb +6 -0
- data/spec/lita/handlers/locker_http_spec.rb +11 -0
- data/spec/lita/handlers/locker_labels_spec.rb +147 -0
- data/spec/lita/handlers/locker_misc_spec.rb +90 -0
- data/spec/lita/handlers/locker_resources_spec.rb +74 -0
- data/spec/lita/handlers/locker_spec.rb +38 -261
- data/spec/spec_helper.rb +12 -0
- metadata +36 -17
- data/TODO.md +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c652f7dfc79a47babe632a2f9516bfeedf1b4781
|
4
|
+
data.tar.gz: d4f5f7802f48182a08fab5f573f44b35ecac6b90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9113338335470eca38f6b2b947618b115c624ffeea5dc81acf94e43636bb1aaecc359f00128653784aace1ed48647e2da0ec5dad5318d90b533e361d66a5fe5
|
7
|
+
data.tar.gz: 2acb94c1f70b702c67baedb3e2cd8095a68c79517c1ec46e57558e8d755e18a203bc5d6987181301999ce1e67aada7cb028fe91289291e0a55bf650b50dad748
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,26 +1,21 @@
|
|
1
|
-
BlockNesting:
|
2
|
-
Max: 5
|
3
|
-
|
4
1
|
ClassLength:
|
5
|
-
Max:
|
2
|
+
Max: 103
|
6
3
|
|
7
4
|
CyclomaticComplexity:
|
8
|
-
Max:
|
9
|
-
|
10
|
-
Documentation:
|
11
|
-
Exclude:
|
12
|
-
- lib/lita/handlers/locker.rb
|
5
|
+
Max: 7
|
13
6
|
|
14
7
|
FileName:
|
15
8
|
Exclude:
|
16
9
|
- lib/lita-locker.rb
|
17
10
|
|
18
11
|
MethodLength:
|
19
|
-
|
12
|
+
Max: 31
|
13
|
+
|
14
|
+
PerceivedComplexity:
|
15
|
+
Max: 12
|
20
16
|
|
21
17
|
LineLength:
|
22
|
-
Max:
|
18
|
+
Max: 120
|
23
19
|
|
24
|
-
|
25
|
-
|
26
|
-
- lib/lita/handlers/locker.rb
|
20
|
+
AbcSize:
|
21
|
+
Max: 49
|
data/.travis.yml
CHANGED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
Pull requests are awesome! Pull requests with tests are even more awesome!
|
2
|
+
|
3
|
+
## Quick steps
|
4
|
+
|
5
|
+
1. Fork the repo.
|
6
|
+
2. Run the tests: `bundle && rake`
|
7
|
+
3. Add a test for your change. Only refactoring and documentation changes require no new tests. If you are adding functionality or fixing a bug, it needs a test!
|
8
|
+
4. Make the test pass.
|
9
|
+
5. Push to your fork and submit a pull request.
|
data/Gemfile
CHANGED
data/lib/lita-locker.rb
CHANGED
@@ -4,4 +4,14 @@ Lita.load_locales Dir[File.expand_path(
|
|
4
4
|
File.join('..', '..', 'locales', '*.yml'), __FILE__
|
5
5
|
)]
|
6
6
|
|
7
|
+
require 'locker/label'
|
8
|
+
require 'locker/misc'
|
9
|
+
require 'locker/regex'
|
10
|
+
require 'locker/resource'
|
11
|
+
|
12
|
+
require 'lita/handlers/locker_events'
|
13
|
+
require 'lita/handlers/locker_http'
|
14
|
+
require 'lita/handlers/locker_labels'
|
15
|
+
require 'lita/handlers/locker_misc'
|
16
|
+
require 'lita/handlers/locker_resources'
|
7
17
|
require 'lita/handlers/locker'
|
data/lib/lita/handlers/locker.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
module Lita
|
2
|
+
# Handy, isn't it?
|
2
3
|
module Handlers
|
4
|
+
# Top-level class for Locker
|
3
5
|
class Locker < Handler
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
RESOURCE_REGEX = /([\.\w-]+)/
|
9
|
-
COMMENT_REGEX = /(\s\#.+)?/
|
6
|
+
include ::Locker::Label
|
7
|
+
include ::Locker::Misc
|
8
|
+
include ::Locker::Regex
|
9
|
+
include ::Locker::Resource
|
10
10
|
|
11
11
|
route(
|
12
|
-
|
12
|
+
/^#{LOCK_REGEX}#{LABEL_REGEX}#{COMMENT_REGEX}$/,
|
13
13
|
:lock
|
14
14
|
)
|
15
15
|
|
16
16
|
route(
|
17
|
-
|
17
|
+
/^#{UNLOCK_REGEX}#{LABEL_REGEX}#{COMMENT_REGEX}$/,
|
18
18
|
:unlock
|
19
19
|
)
|
20
20
|
|
@@ -39,435 +39,84 @@ module Lita
|
|
39
39
|
help: { t('help.steal.syntax') => t('help.steal.desc') }
|
40
40
|
)
|
41
41
|
|
42
|
-
route(
|
43
|
-
/^locker\sstatus\s#{LABEL_REGEX}$/,
|
44
|
-
:status,
|
45
|
-
command: true,
|
46
|
-
help: { t('help.status.syntax') => t('help.status.desc') }
|
47
|
-
)
|
48
|
-
|
49
|
-
route(
|
50
|
-
/^locker\sresource\slist$/,
|
51
|
-
:resource_list,
|
52
|
-
command: true,
|
53
|
-
help: { t('help.resource.list.syntax') => t('help.resource.list.desc') }
|
54
|
-
)
|
55
|
-
|
56
|
-
route(
|
57
|
-
/^locker\sresource\screate\s#{RESOURCE_REGEX}$/,
|
58
|
-
:resource_create,
|
59
|
-
command: true,
|
60
|
-
restrict_to: [:locker_admins],
|
61
|
-
help: {
|
62
|
-
t('help.resource.create.syntax') => t('help.resource.create.desc')
|
63
|
-
}
|
64
|
-
)
|
65
|
-
|
66
|
-
route(
|
67
|
-
/^locker\sresource\sdelete\s#{RESOURCE_REGEX}$/,
|
68
|
-
:resource_delete,
|
69
|
-
command: true,
|
70
|
-
restrict_to: [:locker_admins],
|
71
|
-
help: {
|
72
|
-
t('help.resource.delete.syntax') => t('help.resource.delete.desc')
|
73
|
-
}
|
74
|
-
)
|
75
|
-
|
76
|
-
route(
|
77
|
-
/^locker\sresource\sshow\s#{RESOURCE_REGEX}$/,
|
78
|
-
:resource_show,
|
79
|
-
command: true,
|
80
|
-
help: { t('help.resource.show.syntax') => t('help.resource.show.desc') }
|
81
|
-
)
|
82
|
-
|
83
|
-
route(
|
84
|
-
/^locker\slabel\slist$/,
|
85
|
-
:label_list,
|
86
|
-
command: true,
|
87
|
-
help: { t('help.label.list.syntax') => t('help.label.list.desc') }
|
88
|
-
)
|
89
|
-
|
90
|
-
route(
|
91
|
-
/^locker\slabel\screate\s#{LABEL_REGEX}$/,
|
92
|
-
:label_create,
|
93
|
-
command: true,
|
94
|
-
help: { t('help.label.create.syntax') => t('help.label.create.desc') }
|
95
|
-
)
|
96
|
-
|
97
|
-
route(
|
98
|
-
/^locker\slabel\sdelete\s#{LABEL_REGEX}$/,
|
99
|
-
:label_delete,
|
100
|
-
command: true,
|
101
|
-
help: { t('help.label.delete.syntax') => t('help.label.delete.desc') }
|
102
|
-
)
|
103
|
-
|
104
|
-
route(
|
105
|
-
/^locker\slabel\sshow\s#{LABEL_REGEX}$/,
|
106
|
-
:label_show,
|
107
|
-
command: true,
|
108
|
-
help: { t('help.label.show.syntax') => t('help.label.show.desc') }
|
109
|
-
)
|
110
|
-
|
111
|
-
route(
|
112
|
-
/^locker\slabel\sadd\s#{RESOURCE_REGEX}\sto\s#{LABEL_REGEX}$/,
|
113
|
-
:label_add,
|
114
|
-
command: true,
|
115
|
-
help: { t('help.label.add.syntax') => t('help.label.add.desc') }
|
116
|
-
)
|
117
|
-
|
118
|
-
route(
|
119
|
-
/^locker\slabel\sremove\s#{RESOURCE_REGEX}\sfrom\s#{LABEL_REGEX}$/,
|
120
|
-
:label_remove,
|
121
|
-
command: true,
|
122
|
-
help: { t('help.label.remove.syntax') => t('help.label.remove.desc') }
|
123
|
-
)
|
124
|
-
|
125
|
-
def http_label_show(request, response)
|
126
|
-
name = request.env['router.params'][:name]
|
127
|
-
response.headers['Content-Type'] = 'application/json'
|
128
|
-
response.write(label(name).to_json)
|
129
|
-
end
|
130
|
-
|
131
|
-
def http_resource_show(request, response)
|
132
|
-
name = request.env['router.params'][:name]
|
133
|
-
response.headers['Content-Type'] = 'application/json'
|
134
|
-
response.write(resource(name).to_json)
|
135
|
-
end
|
136
|
-
|
137
42
|
def lock(response)
|
138
43
|
name = response.matches[0][0]
|
139
44
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
owner_mention: o.mention_name))
|
154
|
-
else
|
155
|
-
response.reply('(failed) ' + t('label.owned',
|
156
|
-
name: name,
|
157
|
-
owner_name: o.name))
|
158
|
-
end
|
159
|
-
else
|
160
|
-
response.reply('(failed) ' + t('label.dependency'))
|
161
|
-
end
|
162
|
-
end
|
45
|
+
return response.reply('(failed) ' + t('label.does_not_exist', name: name)) unless label_exists?(name)
|
46
|
+
m = label_membership(name)
|
47
|
+
return response.reply('(failed) ' + t('label.no_resources', name: name)) unless m.count > 0
|
48
|
+
return response.reply('(successful) ' + t('label.lock', name: name)) if lock_label!(name, response.user, nil)
|
49
|
+
|
50
|
+
l = label(name)
|
51
|
+
if l['state'] == 'locked'
|
52
|
+
o = Lita::User.find_by_id(l['owner_id'])
|
53
|
+
if o.mention_name
|
54
|
+
response.reply('(failed) ' + t('label.owned_mention',
|
55
|
+
name: name,
|
56
|
+
owner_name: o.name,
|
57
|
+
owner_mention: o.mention_name))
|
163
58
|
else
|
164
|
-
response.reply('(failed) ' + t('label.
|
59
|
+
response.reply('(failed) ' + t('label.owned',
|
60
|
+
name: name,
|
61
|
+
owner_name: o.name))
|
165
62
|
end
|
166
63
|
else
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
l = label(name)
|
175
|
-
if l['state'] == 'unlocked'
|
176
|
-
response.reply('(successful) ' + t('label.is_unlocked',
|
177
|
-
name: name))
|
178
|
-
else
|
179
|
-
if response.user.id == l['owner_id']
|
180
|
-
unlock_label!(name)
|
181
|
-
response.reply('(successful) ' + t('label.unlock', name: name))
|
182
|
-
else
|
183
|
-
o = Lita::User.find_by_id(l['owner_id'])
|
184
|
-
if o.mention_name
|
185
|
-
response.reply('(failed) ' + t('label.owned_mention',
|
186
|
-
name: name,
|
187
|
-
owner_name: o.name,
|
188
|
-
owner_mention: o.mention_name))
|
189
|
-
else
|
190
|
-
response.reply('(failed) ' + t('label.owned',
|
191
|
-
name: name,
|
192
|
-
owner_name: o.name))
|
193
|
-
end
|
64
|
+
msg = '(failed) ' + t('label.dependency') + "\n"
|
65
|
+
deps = []
|
66
|
+
label_membership(name).each do |resource_name|
|
67
|
+
resource = resource(resource_name)
|
68
|
+
u = Lita::User.find_by_id(resource['owner_id'])
|
69
|
+
if resource['state'] == 'locked'
|
70
|
+
deps.push "#{resource_name} - #{u.name}"
|
194
71
|
end
|
195
72
|
end
|
196
|
-
|
197
|
-
response.reply(
|
73
|
+
msg += deps.join("\n")
|
74
|
+
response.reply(msg)
|
198
75
|
end
|
199
76
|
end
|
200
77
|
|
201
|
-
def
|
78
|
+
def unlock(response)
|
202
79
|
name = response.matches[0][0]
|
203
|
-
|
80
|
+
return response.reply('(failed) ' + t('subject.does_not_exist', name: name)) unless label_exists?(name)
|
81
|
+
l = label(name)
|
82
|
+
return response.reply('(successful) ' + t('label.is_unlocked', name: name)) if l['state'] == 'unlocked'
|
83
|
+
|
84
|
+
if response.user.id == l['owner_id']
|
204
85
|
unlock_label!(name)
|
205
86
|
response.reply('(successful) ' + t('label.unlock', name: name))
|
206
|
-
# FIXME: Handle the case where things can't be unlocked?
|
207
|
-
else
|
208
|
-
response.reply('(failed) ' + t('subject.does_not_exist', name: name))
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
def status(response)
|
213
|
-
name = response.matches[0][0]
|
214
|
-
if label_exists?(name)
|
215
|
-
l = label(name)
|
216
|
-
if l['owner_id'] && l['owner_id'] != ''
|
217
|
-
o = Lita::User.find_by_id(l['owner_id'])
|
218
|
-
response.reply(t('label.desc_owner', name: name,
|
219
|
-
state: l['state'],
|
220
|
-
owner_name: o.name))
|
221
|
-
else
|
222
|
-
response.reply(t('label.desc', name: name, state: l['state']))
|
223
|
-
end
|
224
|
-
elsif resource_exists?(name)
|
225
|
-
r = resource(name)
|
226
|
-
response.reply(t('resource.desc', name: name, state: r['state']))
|
227
|
-
else
|
228
|
-
response.reply(t('subject.does_not_exist', name: name))
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
def label_list(response)
|
233
|
-
labels.each do |n|
|
234
|
-
name = n.sub('label_', '')
|
235
|
-
l = label(name)
|
236
|
-
response.reply(t('label.desc', name: name, state: l['state']))
|
237
|
-
end
|
238
|
-
end
|
239
|
-
|
240
|
-
def label_create(response)
|
241
|
-
name = response.matches[0][0]
|
242
|
-
if create_label(name)
|
243
|
-
response.reply(t('label.created', name: name))
|
244
|
-
else
|
245
|
-
response.reply(t('label.exists', name: name))
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
def label_delete(response)
|
250
|
-
name = response.matches[0][0]
|
251
|
-
if delete_label(name)
|
252
|
-
response.reply(t('label.deleted', name: name))
|
253
|
-
else
|
254
|
-
response.reply(t('label.does_not_exist', name: name))
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
def label_show(response)
|
259
|
-
name = response.matches[0][0]
|
260
|
-
if label_exists?(name)
|
261
|
-
members = label_membership(name)
|
262
|
-
if members.count > 0
|
263
|
-
response.reply(t('label.resources', name: name,
|
264
|
-
resources: members.join(', ')))
|
265
|
-
else
|
266
|
-
response.reply(t('label.has_no_resources', name: name))
|
267
|
-
end
|
268
87
|
else
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
label_name = response.matches[0][1]
|
276
|
-
if label_exists?(label_name)
|
277
|
-
if resource_exists?(resource_name)
|
278
|
-
add_resource_to_label(label_name, resource_name)
|
279
|
-
response.reply(t('label.resource_added', label: label_name,
|
280
|
-
resource: resource_name))
|
88
|
+
o = Lita::User.find_by_id(l['owner_id'])
|
89
|
+
if o.mention_name
|
90
|
+
response.reply('(failed) ' + t('label.owned_mention',
|
91
|
+
name: name,
|
92
|
+
owner_name: o.name,
|
93
|
+
owner_mention: o.mention_name))
|
281
94
|
else
|
282
|
-
response.reply(t('
|
95
|
+
response.reply('(failed) ' + t('label.owned',
|
96
|
+
name: name,
|
97
|
+
owner_name: o.name))
|
283
98
|
end
|
284
|
-
else
|
285
|
-
response.reply(t('label.does_not_exist', name: label_name))
|
286
99
|
end
|
287
100
|
end
|
288
101
|
|
289
|
-
def
|
290
|
-
resource_name = response.matches[0][0]
|
291
|
-
label_name = response.matches[0][1]
|
292
|
-
if label_exists?(label_name)
|
293
|
-
if resource_exists?(resource_name)
|
294
|
-
members = label_membership(label_name)
|
295
|
-
if members.include?(resource_name)
|
296
|
-
remove_resource_from_label(label_name, resource_name)
|
297
|
-
response.reply(t('label.resource_removed',
|
298
|
-
label: label_name, resource: resource_name))
|
299
|
-
else
|
300
|
-
response.reply(t('label.does_not_have_resource',
|
301
|
-
label: label_name, resource: resource_name))
|
302
|
-
end
|
303
|
-
else
|
304
|
-
response.reply(t('resource.does_not_exist', name: resource_name))
|
305
|
-
end
|
306
|
-
else
|
307
|
-
response.reply(t('label.does_not_exist', name: label_name))
|
308
|
-
end
|
309
|
-
end
|
310
|
-
|
311
|
-
def resource_list(response)
|
312
|
-
output = ''
|
313
|
-
resources.each do |r|
|
314
|
-
r_name = r.sub('resource_', '')
|
315
|
-
res = resource(r_name)
|
316
|
-
output += t('resource.desc', name: r_name, state: res['state'])
|
317
|
-
end
|
318
|
-
response.reply(output)
|
319
|
-
end
|
320
|
-
|
321
|
-
def resource_create(response)
|
322
|
-
name = response.matches[0][0]
|
323
|
-
if create_resource(name)
|
324
|
-
response.reply(t('resource.created', name: name))
|
325
|
-
else
|
326
|
-
response.reply(t('resource.exists', name: name))
|
327
|
-
end
|
328
|
-
end
|
329
|
-
|
330
|
-
def resource_delete(response)
|
331
|
-
name = response.matches[0][0]
|
332
|
-
if delete_resource(name)
|
333
|
-
response.reply(t('resource.deleted', name: name))
|
334
|
-
else
|
335
|
-
response.reply(t('resource.does_not_exist', name: name))
|
336
|
-
end
|
337
|
-
end
|
338
|
-
|
339
|
-
def resource_show(response)
|
102
|
+
def steal(response)
|
340
103
|
name = response.matches[0][0]
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
redis.hset(label_key, 'state', 'unlocked') unless
|
354
|
-
resource_exists?(name) || label_exists?(name)
|
355
|
-
end
|
356
|
-
|
357
|
-
def delete_label(name)
|
358
|
-
label_key = "label_#{name}"
|
359
|
-
redis.del(label_key) if label_exists?(name)
|
360
|
-
end
|
361
|
-
|
362
|
-
def label_exists?(name)
|
363
|
-
redis.exists("label_#{name}")
|
364
|
-
end
|
365
|
-
|
366
|
-
def label_membership(name)
|
367
|
-
redis.smembers("membership_#{name}")
|
368
|
-
end
|
369
|
-
|
370
|
-
def add_resource_to_label(label, resource)
|
371
|
-
if label_exists?(label) && resource_exists?(resource)
|
372
|
-
redis.sadd("membership_#{label}", resource)
|
373
|
-
end
|
374
|
-
end
|
375
|
-
|
376
|
-
def remove_resource_from_label(label, resource)
|
377
|
-
if label_exists?(label) && resource_exists?(resource)
|
378
|
-
redis.srem("membership_#{label}", resource)
|
379
|
-
end
|
380
|
-
end
|
381
|
-
|
382
|
-
def create_resource(name)
|
383
|
-
resource_key = "resource_#{name}"
|
384
|
-
redis.hset(resource_key, 'state', 'unlocked') unless
|
385
|
-
resource_exists?(name) || label_exists?(name)
|
386
|
-
end
|
387
|
-
|
388
|
-
def delete_resource(name)
|
389
|
-
resource_key = "resource_#{name}"
|
390
|
-
redis.del(resource_key) if resource_exists?(name)
|
391
|
-
end
|
392
|
-
|
393
|
-
def resource_exists?(name)
|
394
|
-
redis.exists("resource_#{name}")
|
395
|
-
end
|
396
|
-
|
397
|
-
def lock_resource!(name, owner, time_until)
|
398
|
-
if resource_exists?(name)
|
399
|
-
resource_key = "resource_#{name}"
|
400
|
-
value = redis.hget(resource_key, 'state')
|
401
|
-
if value == 'unlocked'
|
402
|
-
# FIXME: Race condition!
|
403
|
-
redis.hset(resource_key, 'state', 'locked')
|
404
|
-
redis.hset(resource_key, 'owner_id', owner.id)
|
405
|
-
redis.hset(resource_key, 'until', time_until)
|
406
|
-
true
|
407
|
-
else
|
408
|
-
false
|
409
|
-
end
|
410
|
-
else
|
411
|
-
false
|
412
|
-
end
|
413
|
-
end
|
414
|
-
|
415
|
-
def lock_label!(name, owner, time_until)
|
416
|
-
if label_exists?(name)
|
417
|
-
key = "label_#{name}"
|
418
|
-
members = label_membership(name)
|
419
|
-
members.each do |m|
|
420
|
-
return false unless lock_resource!(m, owner, time_until)
|
421
|
-
end
|
422
|
-
redis.hset(key, 'state', 'locked')
|
423
|
-
redis.hset(key, 'owner_id', owner.id)
|
424
|
-
redis.hset(key, 'until', time_until)
|
425
|
-
true
|
426
|
-
else
|
427
|
-
false
|
428
|
-
end
|
429
|
-
end
|
430
|
-
|
431
|
-
def unlock_resource!(name)
|
432
|
-
if resource_exists?(name)
|
433
|
-
key = "resource_#{name}"
|
434
|
-
redis.hset(key, 'state', 'unlocked')
|
435
|
-
redis.hset(key, 'owner_id', '')
|
436
|
-
else
|
437
|
-
false
|
438
|
-
end
|
439
|
-
end
|
440
|
-
|
441
|
-
def unlock_label!(name)
|
442
|
-
if label_exists?(name)
|
443
|
-
key = "label_#{name}"
|
444
|
-
members = label_membership(name)
|
445
|
-
members.each do |m|
|
446
|
-
unlock_resource!(m)
|
447
|
-
end
|
448
|
-
redis.hset(key, 'state', 'unlocked')
|
449
|
-
redis.hset(key, 'owner_id', '')
|
450
|
-
true
|
104
|
+
return response.reply('(failed) ' + t('subject.does_not_exist', name: name)) unless label_exists?(name)
|
105
|
+
l = label(name)
|
106
|
+
return response.reply(t('steal.already_unlocked', label: name)) unless l['state'] == 'locked'
|
107
|
+
o = Lita::User.find_by_id(l['owner_id'])
|
108
|
+
if o.id != response.user.id
|
109
|
+
unlock_label!(name)
|
110
|
+
lock_label!(name, response.user, nil)
|
111
|
+
mention = o.mention_name ? "(@#{o.mention_name})" : ''
|
112
|
+
response.reply('(successful) ' + t('steal.stolen',
|
113
|
+
label: name,
|
114
|
+
old_owner: o.name,
|
115
|
+
mention: mention))
|
451
116
|
else
|
452
|
-
|
117
|
+
response.reply(t('steal.self'))
|
453
118
|
end
|
454
119
|
end
|
455
|
-
|
456
|
-
def resource(name)
|
457
|
-
redis.hgetall("resource_#{name}")
|
458
|
-
end
|
459
|
-
|
460
|
-
def resources
|
461
|
-
redis.keys('resource_*')
|
462
|
-
end
|
463
|
-
|
464
|
-
def label(name)
|
465
|
-
redis.hgetall("label_#{name}")
|
466
|
-
end
|
467
|
-
|
468
|
-
def labels
|
469
|
-
redis.keys('label_*')
|
470
|
-
end
|
471
120
|
end
|
472
121
|
|
473
122
|
Lita.register_handler(Locker)
|