snarl-snp 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,47 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "snarl-snp"
8
+ gem.summary = %Q{Snarl Network Protocol Client. You can notify to Snarl over LAN.}
9
+ gem.description = %Q{Snarl Network Protocol Client. Snarl is the notification program for Windows. You can send notification messages to Snarl with SNP over LAN.}
10
+ gem.email = "ezookojo@gmail.com"
11
+ gem.homepage = "http://github.com/kitamomonga/snarl-snp"
12
+ gem.authors = ["kitamomonga"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ gem.add_development_dependency "webmock"
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+ require 'spec/rake/spectask'
23
+ Spec::Rake::SpecTask.new(:spec) do |spec|
24
+ spec.libs << 'lib' << 'spec'
25
+ spec.spec_files = FileList['spec/**/*_spec.rb']
26
+ end
27
+
28
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
29
+ spec.libs << 'lib' << 'spec'
30
+ spec.pattern = 'spec/**/*_spec.rb'
31
+ spec.rcov = true
32
+ end
33
+
34
+ task :spec => :check_dependencies
35
+
36
+ task :default => :spec
37
+
38
+ require 'rake/rdoctask'
39
+ Rake::RDocTask.new do |rdoc|
40
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
41
+
42
+ rdoc.rdoc_dir = 'rdoc'
43
+ rdoc.title = "snarl-snp #{version}"
44
+ rdoc.rdoc_files.include('README.rdoc*')
45
+ rdoc.rdoc_files.include('GUIDE.rdoc*')
46
+ rdoc.rdoc_files.include('lib/**/*.rb')
47
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,8 @@
1
+ #!ruby
2
+ require 'rubygems'
3
+ $LOAD_PATH.unshift(File.join(File.dirname(File.expand_path(__FILE__)), '/../lib/'))
4
+ require 'snarl/snp'
5
+
6
+ host = ENV['SNARL_HOST'] || ARGV[0] || '127.0.0.1'
7
+
8
+ Snarl::SNP.ping(host)
@@ -0,0 +1,227 @@
1
+ #!ruby -Ks
2
+
3
+ # require 'rubygems'
4
+ $LOAD_PATH.unshift(File.join(File.dirname(File.expand_path(__FILE__)), '/../lib/'))
5
+ require 'snarl/snp'
6
+
7
+ # You may use Winamp plugin "File Runner" (gen_runner.dll)
8
+ # http://www.geocities.jp/nanasiya3/ext.html#WA-GEN-RUNNER
9
+ #
10
+ # "File Runner" Command: "fullpath_rubyw_with_quote"
11
+ # "File Runner" Parameter: "fullpath_winamp_nowplaying.rb_with_quote" quoted_params
12
+ # quoted_params => "%artist%||%album%||%title%||%tracknumber%||%year%||%genre%||%comment%||%filename%||%index%||icon=>:album"
13
+ # or
14
+ # quoted_params => "%artist%||%album%||%title%||%tracknumber%||%year%||%genre%||%comment%||%filename%||%index%||icon=>c:\icon.jpg"
15
+ # icon=>:album means icon=>"#{File.dirname(%filename%)}\#{%album%}.[jpg|gif|png|bmp]"
16
+ # icon=>:loose means icon=>"Dir.glob(#{File.dirname(%filename%)}\**.[jpg|gif|png|bmp])[0]"
17
+
18
+ # just run me, and you will get parameters infomation.
19
+ # See WinampNowPlaying#warn_paramerter_infomation_and_exit.
20
+ class WinampNowPlaying
21
+
22
+ class MusicData
23
+ WINAMPDATA_ORDER = %w(artist album title tracknumber year genre comment filename index iconinfo)
24
+ def initialize(data)
25
+ @data = data
26
+ end
27
+
28
+ def [](k) ; @data[k] ; end
29
+ def []=(k, v) ; @data[k] = v ; end
30
+
31
+ WINAMPDATA_ORDER.each do |mes|
32
+ eval("def #{mes} ; self['#{mes}'] ; end; def #{mes}=(v) ; self['#{mes}']=v ; end")
33
+ end
34
+ def icon_value
35
+ iconinfo.to_s.scan(/icon=>(.+?)\Z/).flatten[0]
36
+ end
37
+
38
+ def query
39
+ WINAMPDATA_ORDER[0..-2].map do |e|
40
+ s = self.__send__(e)
41
+ if (s.nil? || s.empty?) then '' else s end
42
+ end.join('||')
43
+ end
44
+
45
+ def to_s
46
+ "#{query}||icon=>#{icon_value}"
47
+ end
48
+
49
+ def self.parse(argv)
50
+ self.new(Hash[*WINAMPDATA_ORDER.zip(argv.join(" ").split(/\|\|/)).flatten])
51
+ end
52
+ def icon_mode
53
+ case
54
+ when /icon=>:album\Z/ =~ iconinfo then
55
+ :album
56
+ when /icon=>:loose\Z/ =~ iconinfo then
57
+ :loose
58
+ when /icon=>\Z|icon=>nil\Z|icon=>:default\Z/ =~ iconinfo then
59
+ :default
60
+ when iconinfo.nil? then
61
+ :default
62
+ else
63
+ :user
64
+ end
65
+ end
66
+ end
67
+
68
+ ## Winamp data "icon=>xxxx"
69
+ # icon=>:album
70
+ # use "#{@album}.{gif,png,jpg,bmp}" ,if none, go :default
71
+ # icon=>:loose
72
+ # use "#{@album}.{gif,png,jpg,bmp}", if none, Dir.glob(*.{gif,png,jpg,bmp})[0] , or, go :default
73
+ # icon=>:default
74
+ # use Snarl Setting (maybe Snarl facemark)
75
+ # icon=>full_file_path_for_image
76
+ # use filepath for reading icon(i.e, C:\icon.jpg). separators are '\' or "/"
77
+ # icon=>image_url
78
+ # access url and use it
79
+ class Icon
80
+
81
+ ICON_EXTNAME = %w(gif png jpg bmp jpeg)
82
+
83
+ def initialize(d, strict = false)
84
+ @d = d
85
+ @albumdir = File.dirname(@d['filename']) #or Winamp %folder%
86
+ @strict = strict
87
+ end
88
+
89
+ def expecting_jacketimages
90
+ ICON_EXTNAME.map{|ext| File.join(@albumdir, "#{@d['album']}.#{ext}")}
91
+ end
92
+
93
+ def album_name_image
94
+ expecting_jacketimages.find{|path| FileTest.file?(path)}
95
+ end
96
+
97
+ def albumdir_entries
98
+ albumdir_glob = @albumdir.gsub(/\\/){'/'} + '/*'
99
+ Dir.glob(albumdir_glob)
100
+ end
101
+
102
+ def is_image?(f)
103
+ /#{ICON_EXTNAME.join('|')}/ =~ f
104
+ end
105
+
106
+ def altanative_image
107
+ albumdir_entries.find{|file| is_image?(file)}
108
+ end
109
+
110
+ def user_image
111
+ @d.icon_value
112
+ end
113
+
114
+ def icon
115
+ # xxxx_image actually returns nil.
116
+ case @d.icon_mode
117
+ when :album then album_name_image || nil
118
+ when :loose then album_name_image || altanative_image || nil
119
+ when :default then nil
120
+ when :user then user_image || nil
121
+ end
122
+ end
123
+ end
124
+
125
+ def initialize(host, port, &block)
126
+ warn_paramerter_infomation_and_exit if argv.empty?
127
+
128
+ @host = host || '127.0.0.1'
129
+ @port = port || 9887
130
+ # The following applications are registered with Snarl:
131
+ @app = "Winamp"
132
+ # Notification classes:
133
+ @class = "Now Playing"
134
+ # Message "First Line"
135
+ @title = "Winamp Now Playing:"
136
+ @text = nil
137
+ @icon = nil
138
+
139
+ @log_output = File.join(ENV['HOME'], 'snarl_winamp.log.txt')
140
+ @logger = defined?(Logger) ? Logger.new(@log_output) : nil
141
+ @data = MusicData.parse(argv)
142
+
143
+ yield(self) if block_given?
144
+ end
145
+
146
+ attr_writer :host, :app, :class, :title, :logger, :log_output, :text, :icon
147
+ attr_reader :data
148
+
149
+ def argv
150
+ ARGV
151
+ end
152
+
153
+ def icon
154
+ case
155
+ when %w(default system none).include?(@icon.to_s) then nil
156
+ when @icon.nil? then Icon.new(@data).icon
157
+ when %w(album).include?(@icon.to_s) then Icon.new(@data).icon
158
+ when @icon then @icon
159
+ end
160
+ end
161
+
162
+ def text
163
+ # do not join with "\r\n"
164
+ case
165
+ when @text.kind_of?(Proc) then
166
+ res = @text.call(self)
167
+ when @text.kind_of?(String) then
168
+ res = @text
169
+ else
170
+ res = [@data.title, "#{@data.artist}/#{@data.album}"].join("\n")
171
+ end
172
+ res
173
+ end
174
+
175
+ def show_message
176
+ Snarl::SNP.open(@host, @port) do |c|
177
+ c.logger = @logger if @logger
178
+ c.register(@app)
179
+ c.add_class(@class)
180
+ c.notification(@title, text, icon, 8, @class)
181
+ end
182
+ end
183
+
184
+ def warn_paramerter_infomation_and_exit
185
+ require 'rbconfig'
186
+ warn 'You may use Winamp plugin "File Runner" (gen_runner.dll)'
187
+ warn 'http://www.geocities.jp/nanasiya3/ext.html#WA-GEN-RUNNER'
188
+ warn ''
189
+
190
+ # display path of rubyw.exe
191
+ if Config::CONFIG.has_key?('rubyw_install_name')
192
+ rubyw = File.join(Config::CONFIG['bindir'], Config::CONFIG['rubyw_install_name'])
193
+ warn %Q{"#{rubyw}"}
194
+ else
195
+ warn "*** rubyw is missing? ***"
196
+ end
197
+ # display where_am_i and Winamp param
198
+ me = File.expand_path(__FILE__)
199
+ params = WinampNowPlaying::MusicData::WINAMPDATA_ORDER[0..-2].map{|e| "%#{e}%"}.join('||')
200
+ param = "#{params}||icon=>:album"
201
+ warn %Q{"#{me}" "#{param}"}
202
+ exit(1)
203
+ end
204
+ end
205
+
206
+ if $0 == __FILE__ then
207
+ WinampNowPlaying.new(ENV['SNARL_HOST'], ENV['SNARL_PORT']) do |amp|
208
+ ## The following applications are registered with Snarl: / nil default
209
+ amp.app = "Winamp"
210
+ ## Notification classes: /nil default
211
+ amp.class = "Now Playing"
212
+ ## Message "First Line" / nil default
213
+ amp.title = "Winamp Now Playing:"
214
+ ## Message Body / Proc is called, String is as-is, default is nil
215
+ amp.text = lambda{|x| "#{x.data.title}\n#{x.data.artist}\n#{x.data.album}"}
216
+ ## Message Icon / path is path, :default is Snarl Setting, nil is album
217
+ ## when nil, if playing dir has "#{@album}.{gif,png,jpg,bmp}", use it as Message icon.
218
+ # amp.icon = 'C:\icon.jpg'
219
+
220
+ ## logger for SNP log output
221
+ # require 'logger'
222
+ # output_file = File.join(ENV['HOME'], 'winamp_nowplaying_log_for_rubyw.txt')
223
+ # amp.logger = Logger.new(output_file)
224
+
225
+ amp.show_message
226
+ end
227
+ end
@@ -0,0 +1,35 @@
1
+ #!ruby -Ku
2
+ require 'rubygems'
3
+ require 'open-uri'
4
+ require 'nokogiri'
5
+ $LOAD_PATH.unshift(File.join(File.dirname(File.expand_path(__FILE__)), '/../lib/'))
6
+ require 'snarl/snp'
7
+
8
+ @uri = 'http://weather.yahoo.co.jp/weather/jp/1b/1400.html'
9
+ @host = ENV['SNARL_HOST'] || ARGV[0] || (if ARGV[0] == '-H' then ARGV[1] else nil end)
10
+
11
+ def encode_win(s)
12
+ if s.respond_to?(:encode) then
13
+ s.dup.encode(::Encoding::SHIFT_JIS)
14
+ else
15
+ require 'kconv'
16
+ s.tosjis
17
+ end
18
+ end
19
+
20
+ uri = URI.parse(@uri)
21
+ html = open(uri, 'User-Agent' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 2.0.50727; .NET CLR 1.1.4322)').read
22
+ doc = Nokogiri::HTML.parse(html, nil, 'EUC-JP')
23
+
24
+ place = doc.at('div#cat-pass p').inner_text.split(/>/).last.gsub(/\s+/){''}
25
+ table = doc.at('table.yjw_table tr')
26
+ weather = table.at('img')
27
+
28
+ title = encode_win("Yahoo! Weather\n#{place}")
29
+ text = encode_win(table.at('table').inner_text.gsub(/\s+/){''})
30
+ icon = weather['src']
31
+
32
+ Snarl::SNP.open(@host) do |snp|
33
+ snp.register('Ruby-Snarl')
34
+ snp.notification(title, text, icon, 20)
35
+ end
@@ -0,0 +1,112 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+
3
+ require 'snp'
4
+
5
+ # Usage:
6
+ # On $HOME/.autotest.
7
+ # require 'snarl/autotest'
8
+ # Autotest::Snarl.host = '192.168.0.1'
9
+ module Autotest::Snarl
10
+
11
+ @snarl_host = '127.0.0.1'
12
+ @snarl_port = 9887
13
+
14
+ class << self
15
+ attr_accessor :snarl_host, :snarl_port
16
+ end
17
+
18
+ def self.host
19
+ ENV['SNARL_HOST'] || Autotest::Snarl.snarl_host
20
+ end
21
+ def self.host=(host)
22
+ Autotest::Snarl.snarl_host = host
23
+ end
24
+ def self.port
25
+ ENV['SNARL_PORT'] || Autotest::Snarl.snarl_port
26
+ end
27
+ def self.port=(port)
28
+ Autotest::Snarl.snarl_port = port.to_i
29
+ end
30
+
31
+ # Windows Snarl shortcut's "working folder" (left click property)
32
+ # %HOME%\Application Data\full phat\snarl\styles
33
+ def self.hostdir
34
+ "./"
35
+ end
36
+ def self.icon_ok
37
+ # %HOME%\Application Data\full phat\snarl\styles\ok.png works fine
38
+ "ok.png"
39
+ end
40
+ def self.icon_fail
41
+ "fail.png"
42
+ end
43
+ def self.icon_pending
44
+ "pending.png"
45
+ end
46
+ def self.app
47
+ "Autotest::Snarl"
48
+ end
49
+
50
+ def self.iconset
51
+ {
52
+ :green => File.join(hostdir, icon_ok),
53
+ :red => File.join(hostdir, icon_fail),
54
+ :yellow => File.join(hostdir, icon_pending), # TODO:
55
+ :info => nil
56
+ }
57
+ end
58
+
59
+ def self.classes
60
+ {
61
+ 'green' => 'test ok',
62
+ 'red' => 'test fail',
63
+ 'yellow' => 'test pending',
64
+ 'info' => 'system message'
65
+ }
66
+ end
67
+
68
+ def self.snarl(title, text, status = :info, timeout = nil)
69
+ Snarl::SNP.open(host, port){|c|
70
+ c.iconset(iconset)
71
+ c.register(app)
72
+ c.add_classes(classes)
73
+ c.notification(
74
+ :title => title,
75
+ :text => text,
76
+ :class => status.to_s,
77
+ :timeout => (timeout||10),
78
+ :icon => status)
79
+ }
80
+ end
81
+
82
+ Autotest.add_hook :run do |at|
83
+ snarl("Run", "Run", :info)
84
+ end
85
+
86
+ Autotest.add_hook :red do |at|
87
+ failed_tests = at.files_to_test.inject(0){ |s,a| k,v = a; s + v.size}
88
+ snarl("Tests Failed", "#{failed_tests} tests failed", :red)
89
+ end
90
+
91
+ Autotest.add_hook :green do |at|
92
+ # TODO: "All tests passed (and pending 3)"
93
+ snarl("Tests Passed", "All tests passed", :green)
94
+ end
95
+
96
+ Autotest.add_hook :run do |at|
97
+ snarl("autotest", "autotest was started", :info, 5) if $DEBUG
98
+ end
99
+
100
+ Autotest.add_hook :interrupt do |at|
101
+ snarl("autotest", "autotest was reset", :info, 5) if $DEBUG
102
+ end
103
+
104
+ Autotest.add_hook :quit do |at|
105
+ snarl("autotest", "autotest is exiting", :info, 5) if $DEBUG
106
+ end
107
+
108
+ Autotest.add_hook :all do |at|_hook
109
+ snarl("autotest", "Tests have fully passed", :green)
110
+ end
111
+
112
+ end
@@ -0,0 +1,11 @@
1
+ require 'socket'
2
+
3
+ $LOAD_PATH.unshift(File.dirname(File.expand_path(__FILE__)))
4
+
5
+ require 'snp/action'
6
+ require 'snp/snp'
7
+ require 'snp/request'
8
+ require 'snp/response'
9
+ require 'snp/error'
10
+ require 'snp/config'
11
+ # require 'snp/addon'