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.
@@ -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'