snarl-snp 0.1.1
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/GUIDE.rdoc.ja +126 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +144 -0
- data/README.rdoc.ja +166 -0
- data/Rakefile +47 -0
- data/VERSION +1 -0
- data/exsample/ping.rb +8 -0
- data/exsample/winamp_nowplaying.rb +227 -0
- data/exsample/yahoo_weather.rb +35 -0
- data/lib/snarl/autotest.rb +112 -0
- data/lib/snarl/snp.rb +11 -0
- data/lib/snarl/snp/action.rb +138 -0
- data/lib/snarl/snp/config.rb +32 -0
- data/lib/snarl/snp/error.rb +76 -0
- data/lib/snarl/snp/request.rb +83 -0
- data/lib/snarl/snp/response.rb +36 -0
- data/lib/snarl/snp/snp.rb +142 -0
- data/snarl-snp.gemspec +78 -0
- data/spec/exsample/data/weather_yahoo_co_jp.html +608 -0
- data/spec/exsample/yahoo_weather_spec.rb +22 -0
- data/spec/snp/action_spec.rb +198 -0
- data/spec/snp/config_spec.rb +53 -0
- data/spec/snp/request_spec.rb +72 -0
- data/spec/snp/response_sprc.rb +96 -0
- data/spec/snp/snp_spec.rb +265 -0
- data/spec/spec_helper.rb +20 -0
- metadata +119 -0
@@ -0,0 +1,138 @@
|
|
1
|
+
class Snarl
|
2
|
+
class SNP
|
3
|
+
module Action
|
4
|
+
|
5
|
+
NOTIFICATION_PARAM_ORDER = [:title, :text, :icon, :timeout, :class, :action, :app]
|
6
|
+
|
7
|
+
# Sends a SNP command "register" to Snarl. For registering +app+ to Snarl setting window.
|
8
|
+
# snp.register('Ruby-Snarl')
|
9
|
+
# +app+ :: an application name. Snarl uses it as an application ID.
|
10
|
+
# Snarl::SNP keeps +app+ for add_class method and notification method.
|
11
|
+
# +app+ default is SNP::DEFAULT_APP, 'Ruby-Snarl'.
|
12
|
+
# Returns SNP::Response object.
|
13
|
+
#
|
14
|
+
# Snarl sends back a casual error when +app+ is already registered.
|
15
|
+
# It is treated as SNP::SNPError::Casual::SNP_ERROR_ALREADY_REGISTERED.
|
16
|
+
def register(app=nil)
|
17
|
+
@app = app
|
18
|
+
cmds = {:action => 'register', :app => app}
|
19
|
+
request(Request.new(cmds))
|
20
|
+
end
|
21
|
+
alias :app= :register
|
22
|
+
|
23
|
+
# Sends a SNP command "add_class" to Snarl. For adding +classid+ class and its +classtitle+ nickname.
|
24
|
+
# snp.add_class('green')
|
25
|
+
# snp.add_class('red', 'failure popup')
|
26
|
+
# +classid+ :: classname ID on the registered application
|
27
|
+
# +classtitle+ :: display alias for +classname+, optional
|
28
|
+
# Returns SNP::Response object.
|
29
|
+
# Before adding a class, you should register the application.
|
30
|
+
#
|
31
|
+
# Snarl sends back a casual error when +classid+ is already added.
|
32
|
+
# It is treated as SNP::SNPError::Casual::SNP_ERROR_CLASS_ALREADY_EXISTS.
|
33
|
+
def add_class(classid, classtitle=nil)
|
34
|
+
# TODO: add_class(app=nil, classid, classtitle=nil)
|
35
|
+
# type=SNP#?version=1.0#?action=add_class#?class=t returns (107) Bad Packet
|
36
|
+
raise "#{self}#register(appname) required before add_class" unless @app
|
37
|
+
cmds = {:action => 'add_class', :app => @app, :class => classid.to_s, :title => classtitle}
|
38
|
+
request(Request.new(cmds))
|
39
|
+
end
|
40
|
+
|
41
|
+
# Sends SNP command "notification" to Snarl. For making a popup message itself.
|
42
|
+
# snp.notification('title', 'text', 'icon.jpg', 10, 'classA') # 10 is timeout Integer
|
43
|
+
# snp.notification(:title => 't', :text => 't', :icon => 'i.jpg', :timeout => 10, :class => 'claA')
|
44
|
+
# +title+ :: title of popup. String.
|
45
|
+
# +text+ :: text body of popup. String. linebreaks should be only "\n". "\r" confuses Snarl.
|
46
|
+
# +icon+ :: icon image path of popup. String/#to_s. path on Snarl machine or http URL. bmp/jpg/png/gif.
|
47
|
+
# +timeout+ :: display seconds of popup. Integer. if nil, DEFAULT_TIMEOUT 10. if 0, popup never closes automatically.
|
48
|
+
# +class+ :: classid of popup. String. It should have been added by "add_class" method when you use.
|
49
|
+
# notification(title, text, icon=nil, timeout=nil, classid=nil) or notification(keyword-hash).
|
50
|
+
# snp.notification('title', 'text', 10)
|
51
|
+
# snp.notification('title', 'text')
|
52
|
+
# snp.notification('text') # title == DEFAULT_APP == 'Ruby-Snarl'
|
53
|
+
def notification(*keyhash)
|
54
|
+
# TODO: priority
|
55
|
+
cmds = normalize_notification_params(keyhash)
|
56
|
+
request(Request.new(cmds))
|
57
|
+
end
|
58
|
+
alias :notify :notification
|
59
|
+
|
60
|
+
# Sends SNP command "unregister" to Snarl. For removing +app+ from Snarl setting window.
|
61
|
+
# snp.unregister('Ruby-Snarl')
|
62
|
+
# After this, Snarl users can not edit the settings for +app+ 's popup.
|
63
|
+
# If you allow users to edit settings, do not send unregister.
|
64
|
+
# Without sending unregister, the applications are always reseted when Snarl restarts.
|
65
|
+
#
|
66
|
+
# Snarl sends back a casual error when +app+ is not registered.
|
67
|
+
# It is treated as SNP::SNPError::Casual::SNP_ERROR_NOT_REGISTERED.
|
68
|
+
def unregister(app=nil)
|
69
|
+
app = app || @app
|
70
|
+
raise "#{self}#unregister requires appname." unless app
|
71
|
+
cmds = {:action => 'unregister', :app => app}
|
72
|
+
request(Request.new(cmds))
|
73
|
+
end
|
74
|
+
|
75
|
+
# Sends SNP command "hello".
|
76
|
+
# irb> Snarl::SNP.new('127.0.0.1').hello
|
77
|
+
# SNP/1.1/0/OK/Snarl R2.21
|
78
|
+
def hello
|
79
|
+
request(Request.new({:action => 'hello'}))
|
80
|
+
end
|
81
|
+
|
82
|
+
# Sends SNP command "version".
|
83
|
+
# irb> Snarl::SNP.new('127.0.0.1').version
|
84
|
+
# SNP/1.1/0/OK/40.15
|
85
|
+
def version
|
86
|
+
request(Request.new({:action => 'version'}))
|
87
|
+
end
|
88
|
+
|
89
|
+
# UTILS -----------------------------
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def paramarray_to_hash(param_array)
|
94
|
+
title, text, icon, timeout, classid, action, app = param_array
|
95
|
+
pattern = {
|
96
|
+
:only_text => (param_array.size == 1),
|
97
|
+
:text_timeout => (param_array.size == 2) && title && text.kind_of?(Integer),
|
98
|
+
:title_text_timeout => (param_array.size == 3) && title && text && icon.kind_of?(Integer)
|
99
|
+
}
|
100
|
+
case
|
101
|
+
when pattern[:only_text] then # notify("msg")
|
102
|
+
{:title => nil, :text => title}
|
103
|
+
when pattern[:text_timeout] then # notify("msg", 10)
|
104
|
+
{:title => nil, :text => title, :timeout => text}
|
105
|
+
when pattern[:title_text_timeout] then # notify("tit", "msg", 10)
|
106
|
+
{:title => title, :text => text, :timeout => icon}
|
107
|
+
else
|
108
|
+
Hash[*NOTIFICATION_PARAM_ORDER.zip(param_array).flatten].delete_if{|k, v| v.nil?}
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# we support for:
|
113
|
+
# notify( 'text')
|
114
|
+
# notify('title', 'text')
|
115
|
+
# notify( 'text', 10)
|
116
|
+
# notify('title', 'text', 10)
|
117
|
+
def normalize_notification_params(param)
|
118
|
+
res = Hash.new
|
119
|
+
if param[0].kind_of?(Hash) then
|
120
|
+
keyhash = param[0]
|
121
|
+
else
|
122
|
+
keyhash = paramarray_to_hash(param)
|
123
|
+
end
|
124
|
+
NOTIFICATION_PARAM_ORDER.each do |command|
|
125
|
+
keyhash_value = (keyhash[command.to_s] || keyhash[command])
|
126
|
+
res[command] = keyhash_value if keyhash_value
|
127
|
+
end
|
128
|
+
res[:action] = 'notification'
|
129
|
+
res[:app] = @app if (res[:app].nil? && @app) # default notification
|
130
|
+
res[:app] = nil if res[:app] == :anonymous # from snp.show_message
|
131
|
+
res[:title] = (@title || DEFAULT_TITLE) unless res[:title]
|
132
|
+
res[:timeout] = (@timeout || DEFAULT_TIMEOUT) unless res[:timeout]
|
133
|
+
res[:icon] = icon(res[:icon]) if res[:icon]
|
134
|
+
return res
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
# when config file exists, require this config
|
3
|
+
class Snarl
|
4
|
+
class SNP
|
5
|
+
class Config
|
6
|
+
|
7
|
+
DEFAULT_HOST = '127.0.0.1'
|
8
|
+
DEFAULT_PORT = 9887
|
9
|
+
@host = nil
|
10
|
+
@port = nil
|
11
|
+
|
12
|
+
def self.host
|
13
|
+
@host || ENV['SNARL_HOST'] || DEFAULT_HOST
|
14
|
+
end
|
15
|
+
def self.host=(v)
|
16
|
+
@host = if v then v.to_s else nil end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.port
|
20
|
+
@port || ENV['SNARL_PORT'] || DEFAULT_PORT
|
21
|
+
end
|
22
|
+
def self.port=(v)
|
23
|
+
@port = if v then v.to_i else nil end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.reset
|
27
|
+
self.host = nil
|
28
|
+
self.port = nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
class Snarl
|
2
|
+
class SNP
|
3
|
+
module Error
|
4
|
+
class SNPError < StandardError
|
5
|
+
def initialize(response, request=nil) # request is String or Request
|
6
|
+
@response, @request = response, request
|
7
|
+
end
|
8
|
+
attr_accessor :request, :response
|
9
|
+
def code ; @response.code ; end
|
10
|
+
def message ; "(#{code}) #{@response.message}" ; end
|
11
|
+
def ok? ; @response.ok? ; end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Casual < SNPError ; end
|
15
|
+
|
16
|
+
class SNP_OK < Casual ; end
|
17
|
+
# (0) OK
|
18
|
+
|
19
|
+
class SNP_ERROR_NOT_REGISTERED < Casual ; end
|
20
|
+
# (202) The application hasn't been registered.
|
21
|
+
|
22
|
+
class SNP_ERROR_ALREADY_REGISTERED < Casual ; end
|
23
|
+
# (203) The application is already registered.
|
24
|
+
|
25
|
+
class SNP_ERROR_CLASS_ALREADY_EXISTS < Casual ; end
|
26
|
+
# (204) Class is already registered.
|
27
|
+
|
28
|
+
class Fatal < SNPError ; end
|
29
|
+
|
30
|
+
class SNP_ERROR_FAILED < Fatal ; end
|
31
|
+
# (101) An internal error occurred - usually this represents a fault within Snarl itself.
|
32
|
+
|
33
|
+
class SNP_ERROR_UNKNOWN_COMMAND < Fatal ; end
|
34
|
+
# (102) An unknown action was specified.
|
35
|
+
|
36
|
+
class SNP_ERROR_TIMED_OUT < Fatal ; end
|
37
|
+
# (103) The command sending (or subsequent reply) timed out.
|
38
|
+
|
39
|
+
class SNP_ERROR_BAD_PACKET < Fatal ; end
|
40
|
+
# (107) The command packet is wrongly formed.
|
41
|
+
|
42
|
+
class SNP_ERROR_NOT_RUNNING < Fatal ; end
|
43
|
+
# (201) Incoming network notification handling has been disabled by the user.
|
44
|
+
|
45
|
+
class RUBYSNARL_UNKNOWN_RESPONSE < Fatal ; end
|
46
|
+
# (???) Snarl returns unknown return code.
|
47
|
+
|
48
|
+
CODE_TO_OBJ = {
|
49
|
+
'0' => SNP_OK,
|
50
|
+
'101' => SNP_ERROR_FAILED,
|
51
|
+
'102' => SNP_ERROR_UNKNOWN_COMMAND,
|
52
|
+
'103' => SNP_ERROR_TIMED_OUT,
|
53
|
+
'107' => SNP_ERROR_BAD_PACKET,
|
54
|
+
'201' => SNP_ERROR_NOT_RUNNING,
|
55
|
+
'202' => SNP_ERROR_NOT_REGISTERED,
|
56
|
+
'203' => SNP_ERROR_ALREADY_REGISTERED,
|
57
|
+
'204' => SNP_ERROR_CLASS_ALREADY_EXISTS
|
58
|
+
}
|
59
|
+
|
60
|
+
def self.klass(response, request=nil)
|
61
|
+
if klass = Error::CODE_TO_OBJ[response.to_s] then
|
62
|
+
klass
|
63
|
+
elsif response.kind_of?(Error::SNPError)
|
64
|
+
response
|
65
|
+
else
|
66
|
+
Error::RUBYSNARL_UNKNOWN_RESPONSE
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.raise(response, request)
|
71
|
+
Error.klass.new(response, request)
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
class Snarl
|
2
|
+
class SNP
|
3
|
+
class Request
|
4
|
+
PROTOCOL_NAME = "SNP"
|
5
|
+
PROTOCOL_VERSION ="1.0"
|
6
|
+
|
7
|
+
SNP_ACTIONS = {
|
8
|
+
'register' => %w(type version action app),
|
9
|
+
'add_class' => %w(type version action app class title),
|
10
|
+
'notification' => %w(type version action app class title text timeout icon priority),
|
11
|
+
'unregister' => %w(type version action app),
|
12
|
+
'hello' => %w(type version action),
|
13
|
+
'version' => %w(type version action),
|
14
|
+
}
|
15
|
+
|
16
|
+
# You have to send non-ascii messages by "Windows" encoding.
|
17
|
+
ENCODING = 'cp932'
|
18
|
+
|
19
|
+
SNP_SEPARATOR = '#?'
|
20
|
+
SNP_TERMINAL_STRING = "\r\n"
|
21
|
+
SNP_HEADER = {'type' => PROTOCOL_NAME, 'version' => PROTOCOL_VERSION}
|
22
|
+
|
23
|
+
# make SNP request string from command hash and is Request object.
|
24
|
+
def initialize(cmd_hash={})
|
25
|
+
@commands = {}.update(cmd_hash)
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :commands
|
29
|
+
|
30
|
+
# Adds command key and value to Request
|
31
|
+
def []=(cmdkey, value) ; @commands[cmdkey] = value ; end # TODO: normalize
|
32
|
+
# Returns command value for command key
|
33
|
+
def [](cmdkey) ; @commands[cmdkey] ; end
|
34
|
+
|
35
|
+
# Returns Request query string with SNP_TERMINAL_STRING "\r\n"
|
36
|
+
def to_str ; query + SNP_TERMINAL_STRING ; end # FIXME: include "\r\n"?
|
37
|
+
alias :to_s :to_str
|
38
|
+
# Returns Request query string. has no SNP_TERMINAL_STRING "\r\n".
|
39
|
+
def inspect ; query ; end
|
40
|
+
def action ; @commands['action'] ; end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def order_command_pair
|
45
|
+
action = @commands['action']
|
46
|
+
@commands.to_a.sort_by{|pair| SNP_ACTIONS[action].index(pair[0])}
|
47
|
+
end
|
48
|
+
|
49
|
+
def query
|
50
|
+
normalize
|
51
|
+
order_command_pair.map{|pair| pair.join('=')}.join(SNP_SEPARATOR)
|
52
|
+
end
|
53
|
+
|
54
|
+
# normalize item pairs
|
55
|
+
# - symbol keys and upcase KEYS are normalized into downcased string keys.
|
56
|
+
# - query should not have any "\r". use "\n"
|
57
|
+
# - when value is nil, delete the item pair.
|
58
|
+
def normalize
|
59
|
+
norm_commands = Hash[*@commands.map{|k, v| [crlf2lf(k).downcase, crlf2lf(v)]}.flatten]
|
60
|
+
action = normalize_action(norm_commands['action'])
|
61
|
+
norm_commands['action'] = action
|
62
|
+
@commands = SNP_HEADER.dup
|
63
|
+
available_commands_in(action).each do |cmd|
|
64
|
+
@commands[cmd] = norm_commands[cmd] if norm_commands[cmd]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def normalize_action(action_type)
|
69
|
+
action_type.downcase.gsub(/-/){'_'}.sub(/\Aaddclass\Z/){'add_class'}
|
70
|
+
end
|
71
|
+
|
72
|
+
def available_commands_in(action)
|
73
|
+
SNP_ACTIONS[action] || {}
|
74
|
+
end
|
75
|
+
|
76
|
+
def crlf2lf(s)
|
77
|
+
s ? s.to_s.gsub(/\r\n/){"\n"}.gsub(/\r/){"\n"} : s
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Snarl
|
2
|
+
class SNP
|
3
|
+
class Response
|
4
|
+
ResponseParseRegexp = /\ASNP\/[\d\.]+\/(\d+)\/(.+?)\Z/
|
5
|
+
def initialize(s)
|
6
|
+
if s.respond_to?(:get) then
|
7
|
+
@response = s.get
|
8
|
+
else
|
9
|
+
@response = s
|
10
|
+
end
|
11
|
+
parse_response
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :code, :message, :infomation, :response
|
15
|
+
attr_accessor :request
|
16
|
+
alias :status :code
|
17
|
+
|
18
|
+
def parse_response
|
19
|
+
if ResponseParseRegexp =~ @response.chomp then
|
20
|
+
@code = $1
|
21
|
+
@message, @infomation= $2.split(/\//)
|
22
|
+
else
|
23
|
+
raise Snarl::SNP::Error::RUBYSNARL_UNKNOWN_RESPONSE.new(self, nil)
|
24
|
+
end
|
25
|
+
raise error.new(self, nil) unless ok?
|
26
|
+
end
|
27
|
+
|
28
|
+
def error ; Error.klass(self.code) ; end
|
29
|
+
|
30
|
+
def to_s ; code ; end # puts response #=> "0"
|
31
|
+
def inspect ; @response.chomp ; end # p response #=> "SNP/1.1/0/OK/456"
|
32
|
+
|
33
|
+
def ok? ; code.to_i.zero? ; end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
class Snarl # conpat for ruby-snarl
|
2
|
+
|
3
|
+
class SNP
|
4
|
+
|
5
|
+
include Action
|
6
|
+
|
7
|
+
# default "timeout command" value. popup disappers in 10 seconds.
|
8
|
+
DEFAULT_TIMEOUT = 10
|
9
|
+
|
10
|
+
# default title for "non-title" notification
|
11
|
+
DEFAULT_TITLE = 'Ruby-Snarl'
|
12
|
+
|
13
|
+
# Snarl::SNP.new('127.0.0.1', 9887)
|
14
|
+
def initialize(host=nil, port=nil, verbose=false)
|
15
|
+
@host = host
|
16
|
+
@port = port
|
17
|
+
@verbose = verbose
|
18
|
+
@logger = nil
|
19
|
+
@app = nil
|
20
|
+
@timeout = nil
|
21
|
+
@iconset = {}
|
22
|
+
@title = nil
|
23
|
+
end
|
24
|
+
|
25
|
+
# When you set it true, all unimportant SNP errors raise.
|
26
|
+
# Default is false, Snarl::SNP::Error::Casual are disabled.
|
27
|
+
attr_accessor :verbose
|
28
|
+
|
29
|
+
# a value of SNP command "app".
|
30
|
+
attr_reader :app
|
31
|
+
|
32
|
+
attr_accessor :title
|
33
|
+
|
34
|
+
# a value of SNP command "timeout".
|
35
|
+
attr_accessor :timeout
|
36
|
+
|
37
|
+
# set Logger object. It is used when sending request and getting response.
|
38
|
+
def logger=(logger)
|
39
|
+
@logger = (logger.kind_of?(Class) ? logger.new($stdout) : logger)
|
40
|
+
end
|
41
|
+
|
42
|
+
# send Snarl::SNP::Request/Hash/String and get Snarl::SNP::Response fron Snarl.
|
43
|
+
# When the response "fatal" response, raise errors.
|
44
|
+
# When method +verbose+ returns true, "casual" errors also raises.
|
45
|
+
def request(req)
|
46
|
+
req = Request.new(req) if req.kind_of?(Hash)
|
47
|
+
debug(req)
|
48
|
+
begin
|
49
|
+
action = req.kind_of?(Request) ? req.action : '(string)'
|
50
|
+
res = get_response(req)
|
51
|
+
info("#{action}: #{res.inspect}")
|
52
|
+
rescue Error::Casual => ex
|
53
|
+
info("#{action}: (ignored) #{ex.message}")
|
54
|
+
raise if verbose
|
55
|
+
rescue Error::Fatal => ex
|
56
|
+
info("#{action}: #{ex.message}")
|
57
|
+
raise
|
58
|
+
end
|
59
|
+
return res
|
60
|
+
end
|
61
|
+
|
62
|
+
# SHORTCUT METHODS ----------------
|
63
|
+
|
64
|
+
# add_classes('type1', 'type2', 'type3')
|
65
|
+
# add_classes(['type1', desc1], ['type2', desc2], ['type3', desc3])
|
66
|
+
def add_classes(*classes)
|
67
|
+
classes.each do |classpair|
|
68
|
+
classpair = [classpair, nil] if classpair.kind_of?(String)
|
69
|
+
add_class(*classpair)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# returns icon path if SNP knows. optional.
|
74
|
+
def icon(s)
|
75
|
+
if @iconset.has_key?(s) then @iconset[s] else s end
|
76
|
+
end
|
77
|
+
|
78
|
+
# set icons pair. quite optional.
|
79
|
+
# snp.iconset(:red => 'red.jpg')
|
80
|
+
# snp.notification('title', 'text', :red) #=> sends "icon=red.jpg"
|
81
|
+
# snp.notification('title', 'text', 'blue') #=> sends "icon=blue"
|
82
|
+
def iconset(icons)
|
83
|
+
@iconset = icons
|
84
|
+
end
|
85
|
+
alias :icons :iconset
|
86
|
+
|
87
|
+
def ping
|
88
|
+
notification(DEFAULT_TITLE, 'Ruby Snarl-SNP Ping Message', 3, nil)
|
89
|
+
end
|
90
|
+
|
91
|
+
alias :message :notification
|
92
|
+
|
93
|
+
def snarl_hello
|
94
|
+
hello.infomation
|
95
|
+
end
|
96
|
+
|
97
|
+
def snarl_version
|
98
|
+
version.infomation
|
99
|
+
end
|
100
|
+
|
101
|
+
# Snarl::SNP.open(host, port){|snp| snp.register ... }
|
102
|
+
# "ensure block" is empty. TCPSocket is closed per access.
|
103
|
+
def self.open(host=nil, port=nil, verbose=false, &block)
|
104
|
+
client = new(host, port, verbose)
|
105
|
+
yield(client) # socket always closed in TCPSocket#open{...}
|
106
|
+
client
|
107
|
+
end
|
108
|
+
|
109
|
+
# send message only. app is "anonymous".
|
110
|
+
# Snarl::SNP.show_message(host, 9887, title, text, tomeout, icon)
|
111
|
+
# Snarl::SNP.show_message(host, title, text, tomeout, icon)
|
112
|
+
def self.show_message(host, port, title=nil, text=nil, timeout=nil, icon=nil)
|
113
|
+
# TODO: (host, title, text, 10)
|
114
|
+
if port.kind_of?(String) && icon.nil? then
|
115
|
+
port, title, text, timeout, icon = nil, port, title, text, timeout
|
116
|
+
end
|
117
|
+
new(host, port).notification(:title => title, :text => text, :timeout => timeout, :icon => icon)
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.ping(host=nil, port=nil)
|
121
|
+
new(host, port).ping
|
122
|
+
end
|
123
|
+
# ----------------- SHORTCUT METHODS
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
def get_response(req)
|
128
|
+
host = @host || Config.host
|
129
|
+
port = @port || Config.port
|
130
|
+
TCPSocket.open(host, port) do |s|
|
131
|
+
s.write(req)
|
132
|
+
res = Response.new(s.gets)
|
133
|
+
res.request = req
|
134
|
+
res
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def info(m); @logger.info(m) if @logger; end
|
139
|
+
def debug(m); @logger.debug(m) if @logger; end
|
140
|
+
|
141
|
+
end
|
142
|
+
end
|