signaly-notify 0.0.3 → 0.0.4
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.
- checksums.yaml +4 -4
- data/bin/signaly-notify.rb +259 -165
- metadata +18 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d504ba72d7f41e9ae2d5fecf6ed2d6ac7a821525
|
4
|
+
data.tar.gz: d669974e5f5e67cc144d2ad216897284a50bc5c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f8b1aed68273983cc7c0b862829fc3c4d2960c6c71118271f398310425e97a404113fa4b18fb55415680adc16e85b0b2d8ba0f172581c7d92afc71877815db55
|
7
|
+
data.tar.gz: 024beb8fc12147e2a095839dbcd2aa68631f621674927d1456c33e83bfa90d2366f8b7b40d5fdfb41c27bffdcaa1aead313af0e152b6b8dc491940a1b66861d7
|
data/bin/signaly-notify.rb
CHANGED
@@ -3,42 +3,33 @@
|
|
3
3
|
require 'mechanize' # interaction with websites
|
4
4
|
require 'colorize' # colorful console output
|
5
5
|
require 'highline' # automating some tasks of the cli user interaction
|
6
|
-
require 'libnotify' # visual notification
|
7
6
|
require 'optparse'
|
8
7
|
require 'yaml'
|
9
8
|
|
10
|
-
|
11
|
-
|
9
|
+
# optional gems for visual notifications
|
10
|
+
begin
|
11
|
+
require 'libnotify'
|
12
|
+
rescue LoadError
|
13
|
+
end
|
14
|
+
|
15
|
+
begin
|
16
|
+
require 'ruby-growl'
|
17
|
+
rescue LoadError
|
18
|
+
end
|
19
|
+
|
20
|
+
SNConfig = Struct.new(:sleep_seconds, # between checks
|
21
|
+
:remind_after, # the first notification
|
12
22
|
:notification_showtime,
|
13
23
|
:debug_output,
|
14
24
|
:login,
|
15
|
-
:password
|
25
|
+
:password,
|
26
|
+
:url, # of the checked page
|
27
|
+
:skip_login,
|
28
|
+
:config_file,
|
29
|
+
:console_only,
|
30
|
+
:notify)
|
16
31
|
|
17
|
-
config_layers = []
|
18
|
-
|
19
|
-
config = SNConfig.new
|
20
32
|
defaults = SNConfig.new
|
21
|
-
|
22
|
-
config_layers << defaults
|
23
|
-
config_layers << config
|
24
|
-
|
25
|
-
# merges the config structs so that the last one
|
26
|
-
# in the argument list has the highest priority and value nil is considered
|
27
|
-
# empty
|
28
|
-
def merge_structs(*structs)
|
29
|
-
merged = structs.first.dup
|
30
|
-
|
31
|
-
merged.each_pair do |key, value|
|
32
|
-
k = key.to_s # a sym normally; but we also want to merge a normal Hash received from Yaml
|
33
|
-
structs.each do |s|
|
34
|
-
if s[k] != nil then
|
35
|
-
merged[k] = s[k]
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# set config defaults:
|
42
33
|
# how many seconds between two checks of the site
|
43
34
|
defaults.sleep_seconds = 60
|
44
35
|
# if there is some pending content and I don't look at it,
|
@@ -48,20 +39,14 @@ defaults.remind_after = 60*5
|
|
48
39
|
defaults.notification_showtime = 10
|
49
40
|
defaults.debug_output = false
|
50
41
|
defaults.password = nil
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
m = str.match /\d+/
|
57
|
-
|
58
|
-
unless m
|
59
|
-
return 0
|
60
|
-
end
|
61
|
-
|
62
|
-
return m[0].to_i
|
42
|
+
# use first available visual notification engine
|
43
|
+
if defined? Libnotify
|
44
|
+
defaults.notify = :libnotify
|
45
|
+
elsif defined? Growl
|
46
|
+
defaults.notify = :growl
|
63
47
|
end
|
64
48
|
|
49
|
+
# how many PMs, notifications, invitations a user has at a time
|
65
50
|
class SignalyStatus < Struct.new(:pm, :notifications, :invitations)
|
66
51
|
|
67
52
|
def initialize(pm=0, notifications=0, invitations=0)
|
@@ -73,26 +58,40 @@ class SignalyStatus < Struct.new(:pm, :notifications, :invitations)
|
|
73
58
|
return false
|
74
59
|
end
|
75
60
|
|
76
|
-
#
|
61
|
+
# does self have anything new compared with other?
|
62
|
+
def >(other)
|
63
|
+
if other.nil?
|
64
|
+
return true
|
65
|
+
end
|
77
66
|
|
78
|
-
|
79
|
-
|
80
|
-
|
67
|
+
[:pm, :notifications, :invitations].each do |prop|
|
68
|
+
if send(prop) > other.send(prop) then
|
69
|
+
return true
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
return false
|
74
|
+
end
|
75
|
+
|
76
|
+
# is there any change between old_status and self in property prop?
|
77
|
+
def changed?(old_status, prop)
|
78
|
+
(old_status == nil && self[prop] > 0) ||
|
79
|
+
(old_status != nil && self[prop] != old_status[prop])
|
81
80
|
end
|
82
81
|
end
|
83
82
|
|
83
|
+
# interaction with signaly.cz
|
84
84
|
class SignalyChecker
|
85
|
-
# interaction with signaly.cz
|
86
85
|
|
87
|
-
def initialize(
|
88
|
-
@username =
|
89
|
-
@password = password
|
86
|
+
def initialize(config)
|
87
|
+
@username = config.login
|
88
|
+
@password = config.password
|
90
89
|
|
91
90
|
@agent = Mechanize.new
|
92
91
|
|
93
|
-
@dbg_print_pages =
|
92
|
+
@dbg_print_pages = config.debug_output || false # print raw html of all request results?
|
94
93
|
|
95
|
-
|
94
|
+
@checked_page = config.url || 'https://www.signaly.cz/'
|
96
95
|
end
|
97
96
|
|
98
97
|
USERMENU_XPATH = ".//div[contains(@class, 'section-usermenu')]"
|
@@ -100,7 +99,7 @@ class SignalyChecker
|
|
100
99
|
# takes user name and password; returns a page (logged-in) or throws
|
101
100
|
# exception
|
102
101
|
def login
|
103
|
-
page = @agent.get(
|
102
|
+
page = @agent.get(@checked_page)
|
104
103
|
debug_page_print "front page", page
|
105
104
|
|
106
105
|
login_form = page.form_with(:id => 'frm-loginForm')
|
@@ -130,9 +129,9 @@ class SignalyChecker
|
|
130
129
|
|
131
130
|
def user_status
|
132
131
|
status = SignalyStatus.new
|
133
|
-
page = @agent.get(
|
132
|
+
page = @agent.get(@checked_page)
|
134
133
|
debug_page_print "user main page", page
|
135
|
-
|
134
|
+
|
136
135
|
menu = page.search(USERMENU_XPATH)
|
137
136
|
|
138
137
|
pm = menu.search(".//a[@href='/vzkazy']")
|
@@ -154,14 +153,42 @@ class SignalyChecker
|
|
154
153
|
def debug_page_print(title, page)
|
155
154
|
return if ! @dbg_print_pages
|
156
155
|
|
157
|
-
STDERR.puts
|
158
|
-
STDERR.puts(
|
156
|
+
STDERR.puts
|
157
|
+
STDERR.puts ("# "+title).colorize(:yellow)
|
159
158
|
STDERR.puts
|
160
159
|
STDERR.puts page.search(".//div[@class='navbar navbar-fixed-top section-header']")
|
161
160
|
STDERR.puts
|
162
|
-
STDERR.puts
|
161
|
+
STDERR.puts "-" * 60
|
163
162
|
STDERR.puts
|
164
163
|
end
|
164
|
+
|
165
|
+
# finds the first integer in the string and returns it
|
166
|
+
def find_num(str, default=0)
|
167
|
+
m = str.match /\d+/
|
168
|
+
return m ? m[0].to_i : default
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# dispatches events to observers - subscribed notifiers
|
173
|
+
class Notifier
|
174
|
+
def initialize
|
175
|
+
@outputters = {}
|
176
|
+
end
|
177
|
+
|
178
|
+
def add_outputter(outputter, *events)
|
179
|
+
events.each do |event|
|
180
|
+
@outputters[event] ||= []
|
181
|
+
@outputters[event] << outputter
|
182
|
+
end
|
183
|
+
self
|
184
|
+
end
|
185
|
+
|
186
|
+
def emit(event, *args)
|
187
|
+
if @outputters[event]
|
188
|
+
@outputters[event].each {|o| o.output *args }
|
189
|
+
end
|
190
|
+
self
|
191
|
+
end
|
165
192
|
end
|
166
193
|
|
167
194
|
class SignalyStatusOutputter
|
@@ -187,23 +214,14 @@ class ConsoleOutputter < SignalyStatusOutputter
|
|
187
214
|
puts # start on a new line
|
188
215
|
print t.strftime("%H:%M:%S")
|
189
216
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
ns = new_status[:notifications].to_s
|
197
|
-
if new_status.changed?(old_status, :notifications) then
|
198
|
-
ns = ns.colorize(:red)
|
199
|
-
end
|
200
|
-
print " notifications: "+ns
|
201
|
-
|
202
|
-
is = new_status[:invitations].to_s
|
203
|
-
if new_status.changed?(old_status, :invitations) then
|
204
|
-
is = is.colorize(:red)
|
217
|
+
[:pm, :notifications, :invitations].each do |what|
|
218
|
+
num = new_status[what].to_s
|
219
|
+
if new_status.changed?(old_status, what) then
|
220
|
+
num = num.colorize(:red)
|
221
|
+
end
|
222
|
+
print " #{what}: #{num}"
|
205
223
|
end
|
206
|
-
puts
|
224
|
+
puts
|
207
225
|
end
|
208
226
|
|
209
227
|
# doesn't work....
|
@@ -215,131 +233,207 @@ end
|
|
215
233
|
|
216
234
|
class LibNotifyOutputter < SignalyStatusOutputter
|
217
235
|
def output(new_status, old_status)
|
218
|
-
|
219
|
-
|
236
|
+
text = [:pm, :notifications, :invitations].collect do |what|
|
237
|
+
"#{what}: #{new_status[what]}"
|
238
|
+
end.join "\n"
|
220
239
|
|
221
|
-
|
240
|
+
Libnotify.show(:body => text, :summary => "signaly.cz", :timeout => @config.notification_showtime)
|
241
|
+
end
|
242
|
+
end
|
222
243
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
244
|
+
class GrowlOutputter < SignalyStatusOutputter
|
245
|
+
def output(new_status, old_status)
|
246
|
+
text = [:pm, :notifications, :invitations].collect do |what|
|
247
|
+
"#{what}: #{new_status[what]}"
|
248
|
+
end.join "\n"
|
228
249
|
|
229
|
-
|
250
|
+
notif = Growl.new 'localhost', 'ruby-growl', 'GNTP'
|
251
|
+
notif.notify('signaly.cz', 'signaly.cz', text)
|
230
252
|
end
|
231
253
|
end
|
232
254
|
|
255
|
+
class SignalyNotifyApp
|
233
256
|
|
234
|
-
|
257
|
+
DEFAULT_CONFIG_PATH = ".config/signaly-notify/config.yaml"
|
235
258
|
|
236
|
-
|
237
|
-
config_file = nil
|
238
|
-
default_config_path = "#{ENV['HOME']}/.config/signaly-notify/config.yaml"
|
239
|
-
if default_config_path then
|
240
|
-
config_file = default_config_path
|
241
|
-
end
|
259
|
+
attr_accessor :default_config
|
242
260
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
261
|
+
def call(argv)
|
262
|
+
options = process_options(argv)
|
263
|
+
config = merge_structs(
|
264
|
+
@default_config,
|
265
|
+
config_file(options.config_file),
|
266
|
+
options
|
267
|
+
)
|
268
|
+
ask_config config
|
248
269
|
|
249
|
-
|
250
|
-
config
|
251
|
-
end
|
252
|
-
|
253
|
-
opts.separator "If you don't provide any of the options above, "\
|
254
|
-
"the program will ask you to type the name and/or password on its start. "\
|
255
|
-
"(And especially "\
|
256
|
-
"for the password it's probably a bit safer to type it this way than "\
|
257
|
-
"to type it on the commandline.)\n\n"
|
258
|
-
|
259
|
-
opts.on "-s", "--sleep SECS", Integer, "how many seconds to sleep between two checks (default is #{config.sleep_seconds})" do |s|
|
260
|
-
config.sleep_seconds = s
|
261
|
-
end
|
270
|
+
notifier = Notifier.new
|
271
|
+
prepare_outputters config, notifier
|
262
272
|
|
263
|
-
|
264
|
-
config.remind_after = s
|
273
|
+
check_loop config, notifier
|
265
274
|
end
|
266
275
|
|
267
|
-
|
268
|
-
config.debug_output = true
|
269
|
-
end
|
276
|
+
private
|
270
277
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
end
|
278
|
+
# load configuration from config file
|
279
|
+
def config_file(path=nil)
|
280
|
+
path ||= File.join ENV['HOME'], DEFAULT_CONFIG_PATH
|
275
281
|
|
276
|
-
|
277
|
-
|
282
|
+
if File.exist? path then
|
283
|
+
cfg = YAML.load(File.open(path))
|
284
|
+
# symbolize keys
|
285
|
+
cfg = cfg.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
|
286
|
+
return cfg
|
287
|
+
end
|
288
|
+
|
289
|
+
return nil
|
278
290
|
end
|
279
|
-
end
|
280
|
-
optparse.parse!
|
281
291
|
|
282
|
-
|
283
|
-
|
284
|
-
|
292
|
+
def process_options(argv)
|
293
|
+
config = SNConfig.new
|
294
|
+
optparse = OptionParser.new do |opts|
|
295
|
+
opts.on "-u", "--user NAME", "user name used to log in" do |n|
|
296
|
+
config.login = n
|
297
|
+
end
|
285
298
|
|
286
|
-
|
299
|
+
opts.on "-p", "--password WORD", "user's password" do |p|
|
300
|
+
config.password = p
|
301
|
+
end
|
287
302
|
|
288
|
-
|
289
|
-
|
290
|
-
|
303
|
+
opts.separator "If you don't provide any of the options above, "\
|
304
|
+
"the program will ask you to type the name and/or password on its start. "\
|
305
|
+
"(And especially "\
|
306
|
+
"for the password it's probably a bit safer to type it this way than "\
|
307
|
+
"to type it on the commandline.)\n\n"
|
291
308
|
|
292
|
-
|
293
|
-
|
309
|
+
opts.on "-s", "--sleep SECS", Integer, "how many seconds to sleep between two checks (default is #{config.sleep_seconds})" do |s|
|
310
|
+
config.sleep_seconds = s
|
311
|
+
end
|
294
312
|
|
295
|
-
if
|
296
|
-
|
297
|
-
end
|
313
|
+
opts.on "-r", "--remind SECS", Integer, "if I don't bother about the contents I recieved a notification about, remind me after X seconds (default is #{config.remind_after}; set to 0 to disable)" do |s|
|
314
|
+
config.remind_after = s
|
315
|
+
end
|
298
316
|
|
299
|
-
|
300
|
-
|
301
|
-
end
|
317
|
+
opts.on "--notify NOTIFIER", "choose visual notification engine (possible values are 'libnotify' and 'growl')" do |s|
|
318
|
+
config.notify = s.to_sym
|
319
|
+
end
|
320
|
+
|
321
|
+
opts.on "--console-only", "don't display any visual notifications" do
|
322
|
+
config.console_only = true
|
323
|
+
end
|
324
|
+
|
325
|
+
opts.on "-d", "--debug", "print debugging information to STDERR" do
|
326
|
+
config.debug_output = true
|
327
|
+
end
|
328
|
+
|
329
|
+
opts.on "--url URL", "check URL different from the default (for developmeng)" do |s|
|
330
|
+
config.url = s
|
331
|
+
end
|
332
|
+
|
333
|
+
opts.on "--skip-login", "don't login (for development)" do
|
334
|
+
config.skip_login = true
|
335
|
+
end
|
302
336
|
|
303
|
-
|
337
|
+
opts.on "-h", "--help", "print this help" do
|
338
|
+
puts opts
|
339
|
+
exit 0
|
340
|
+
end
|
341
|
+
|
342
|
+
opts.on "-c", "--config FILE", "configuration file" do |f|
|
343
|
+
config.config_file = f
|
344
|
+
end
|
345
|
+
end
|
346
|
+
optparse.parse! argv
|
347
|
+
|
348
|
+
|
349
|
+
unless argv.empty?
|
350
|
+
STDERR.puts "Warning: unused commandline arguments: "+ARGV.join(', ')
|
351
|
+
end
|
352
|
+
|
353
|
+
return config
|
354
|
+
end
|
355
|
+
|
356
|
+
# ask the user for missing essential information
|
357
|
+
def ask_config(config)
|
358
|
+
cliio = HighLine.new
|
359
|
+
config.login ||= cliio.ask("login: ")
|
360
|
+
config.password ||= cliio.ask("password: ") {|q| q.echo = '*' }
|
361
|
+
end
|
362
|
+
|
363
|
+
# merges the config structs so that the last one
|
364
|
+
# in the argument list has the highest priority and value nil is considered
|
365
|
+
# empty
|
366
|
+
def merge_structs(*structs)
|
367
|
+
merged = structs.shift.dup
|
368
|
+
|
369
|
+
merged.each_pair do |key, value|
|
370
|
+
structs.each do |s|
|
371
|
+
next if s.nil?
|
372
|
+
if s[key] != nil then
|
373
|
+
merged[key] = s[key]
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
304
377
|
|
305
|
-
|
306
|
-
|
378
|
+
return merged
|
379
|
+
end
|
307
380
|
|
308
|
-
|
309
|
-
|
381
|
+
def prepare_outputters(config, notifier)
|
382
|
+
notifier.add_outputter ConsoleOutputter.new(config), :checked
|
310
383
|
|
311
|
-
|
312
|
-
|
384
|
+
return if config.console_only
|
385
|
+
return unless config.notify
|
313
386
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
sleep 21
|
321
|
-
raise
|
387
|
+
case config.notify.to_sym
|
388
|
+
when :libnotify
|
389
|
+
notifier.add_outputter LibNotifyOutputter.new(config), :changed, :remind
|
390
|
+
when :growl
|
391
|
+
notifier.add_outputter GrowlOutputter.new(config), :changed, :remind
|
392
|
+
end
|
322
393
|
end
|
323
394
|
|
324
|
-
|
325
|
-
|
395
|
+
def check_loop(config, notifier)
|
396
|
+
checker = SignalyChecker.new config
|
397
|
+
checker.login unless config.skip_login
|
398
|
+
|
399
|
+
old_status = status = nil
|
400
|
+
last_reminder = 0
|
401
|
+
|
402
|
+
loop do
|
403
|
+
old_status = status
|
404
|
+
|
405
|
+
begin
|
406
|
+
status = checker.user_status
|
407
|
+
rescue Exception, SocketError => e
|
408
|
+
STDERR.puts "#{e.class}: #{e.message}"
|
409
|
+
sleep config.sleep_seconds
|
410
|
+
retry
|
411
|
+
end
|
326
412
|
|
327
|
-
|
413
|
+
notifier.emit :checked, status, old_status
|
328
414
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
lno.output status, old_status
|
334
|
-
last_reminder = Time.now.to_i
|
415
|
+
if status > old_status then
|
416
|
+
# something new
|
417
|
+
notifier.emit :changed, status, old_status
|
418
|
+
last_reminder = Time.now.to_i
|
335
419
|
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
420
|
+
elsif config.remind_after != 0 &&
|
421
|
+
Time.now.to_i >= last_reminder + config.remind_after &&
|
422
|
+
status.is_there_anything? then
|
423
|
+
# nothing new, but pending content should be reminded
|
424
|
+
notifier.emit :remind, status, old_status
|
425
|
+
last_reminder = Time.now.to_i
|
426
|
+
end
|
427
|
+
|
428
|
+
sleep config.sleep_seconds
|
429
|
+
end
|
342
430
|
end
|
431
|
+
end
|
432
|
+
|
433
|
+
|
343
434
|
|
344
|
-
|
435
|
+
if $0 == __FILE__ then
|
436
|
+
app = SignalyNotifyApp.new
|
437
|
+
app.default_config = defaults
|
438
|
+
app.call ARGV
|
345
439
|
end
|
metadata
CHANGED
@@ -1,71 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: signaly-notify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jakub Pavlík
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mechanize
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '2.7'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '2.7'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: colorize
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
33
|
+
version: '0.7'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
40
|
+
version: '0.7'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: highline
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '1.7'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: libnotify
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - '>='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :runtime
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - '>='
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
54
|
+
version: '1.7'
|
69
55
|
description: "signaly-notify.rb is a simple script \nlogging in with your user data
|
70
56
|
to the social network https://signaly.cz \nand notifying you - by the means of printing
|
71
57
|
to the console \nas well as sending a visual notification using libnotify - \nwhen
|
@@ -88,18 +74,19 @@ require_paths:
|
|
88
74
|
- lib
|
89
75
|
required_ruby_version: !ruby/object:Gem::Requirement
|
90
76
|
requirements:
|
91
|
-
- -
|
77
|
+
- - ">="
|
92
78
|
- !ruby/object:Gem::Version
|
93
79
|
version: '0'
|
94
80
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
81
|
requirements:
|
96
|
-
- -
|
82
|
+
- - ">="
|
97
83
|
- !ruby/object:Gem::Version
|
98
84
|
version: '0'
|
99
85
|
requirements: []
|
100
86
|
rubyforge_project:
|
101
|
-
rubygems_version: 2.
|
87
|
+
rubygems_version: 2.2.2
|
102
88
|
signing_key:
|
103
89
|
specification_version: 4
|
104
90
|
summary: notification script for signaly.cz (Czech christian social network)
|
105
91
|
test_files: []
|
92
|
+
has_rdoc:
|