libnotify 0.5.1-universal-rubinius-1.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ doc
2
+ pkg
3
+ coverage
4
+ tags
5
+ .yardoc
6
+ .bundle
7
+ Gemfile.lock
8
+ *.rbc
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm @libnotify --create
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ rvm:
2
+ - ree
3
+ - 1.9.2
4
+ - jruby
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,61 @@
1
+ = Libnotify
2
+
3
+ Ruby bindings for libnotify using FFI.
4
+
5
+ Source[http://github.com/splattael/libnotify] |
6
+ RDoc[http://rdoc.info/github/splattael/libnotify/master/file/README.rdoc]
7
+
8
+ http://github.com/splattael/libnotify/raw/master/libnotify.png
9
+
10
+ == Usage
11
+
12
+ require 'libnotify'
13
+
14
+ # Block syntax
15
+ n = Libnotify.new do |notify|
16
+ notify.summary = "hello"
17
+ notify.body = "world"
18
+ notify.timeout = 1.5 # 1.5 (s), 1000 (ms), "2", nil, false
19
+ notify.urgency = :critical # :low, :normal, :critical
20
+ notify.append = false # default true - append onto existing notification
21
+ notify.icon_path = "/usr/share/icons/gnome/scalable/emblems/emblem-default.svg"
22
+ end
23
+ n.show!
24
+
25
+ # Hash syntax
26
+ Libnotify.show(:body => "hello", :summary => "world", :timeout => 2.5)
27
+
28
+ # Mixed syntax
29
+ Libnotify.show(options) do |n|
30
+ n.timeout = 1.5 # overrides :timeout in options
31
+ end
32
+
33
+ # Icon path auto-detection
34
+ Libnotify.icon_dirs << "/usr/share/icons/gnome/*/"
35
+ Libnotify.show(:icon_path => "emblem-default.png")
36
+ Libnotify.show(:icon_path => :"emblem-default")
37
+
38
+ == Installation
39
+
40
+ gem install libnotify
41
+
42
+ You'll need libnotify. On Debian just type:
43
+
44
+ apt-get install libnotify1
45
+
46
+ == Testing
47
+
48
+ git clone git://github.com/splattael/libnotify.git
49
+ cd libnotify
50
+ (gem install bundler)
51
+ bundle install
52
+ rake
53
+
54
+ == Authors
55
+
56
+ * Peter Suschlik (http://github.com/splattael)
57
+ * Dennis Collective (http://github.com/denniscollective)
58
+
59
+ == TODO
60
+
61
+ * Mock FFI calls with rrriot. (test/test_libnotify.rb:61)
data/Rakefile ADDED
@@ -0,0 +1,66 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ SUPPORTED_RUBIES = %w[ree 1.9.2 jruby rbx]
5
+
6
+ require 'rake'
7
+ require 'rake/rdoctask'
8
+ require 'rubygems'
9
+
10
+ # Test
11
+ require 'rake/testtask'
12
+ desc 'Default: run unit tests.'
13
+ task :default => :test
14
+
15
+ Rake::TestTask.new(:test) do |test|
16
+ test.test_files = FileList.new('test/test_*.rb')
17
+ test.libs << 'test'
18
+ test.verbose = true
19
+ end
20
+
21
+ desc "Test with several ruby versions"
22
+ task :"test:rubies" do
23
+ command = "bundle check || bundle install && rake"
24
+ SUPPORTED_RUBIES.each do |ruby|
25
+ rvm = "#{ruby}@libnotify"
26
+ puts "\n" * 3
27
+ puts "RVM: #{rvm}"
28
+ puts "=" * 40
29
+
30
+ system %{rvm #{rvm} exec bash -c '#{command}'}
31
+ end
32
+ end
33
+
34
+ # Yard
35
+ begin
36
+ require 'yard'
37
+ YARD::Rake::YardocTask.new
38
+ rescue LoadError
39
+ task :yardoc do
40
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
41
+ end
42
+ end
43
+
44
+ desc "Alias for `rake yard`"
45
+ task :doc => :yard
46
+
47
+ # Misc
48
+ desc "Tag files for vim"
49
+ task :ctags do
50
+ dirs = $LOAD_PATH.select {|path| File.directory?(path) }
51
+ system "ctags -R #{dirs.join(" ")}"
52
+ end
53
+
54
+ desc "Find whitespace at line ends"
55
+ task :eol do
56
+ system "grep -nrE ' +$' *"
57
+ end
58
+
59
+ desc "Display TODOs"
60
+ task :todo do
61
+ `grep -Inr TODO lib test`.each do |line|
62
+ line.scan(/^(.*?:.*?):\s*#\s*TODO\s*(.*)$/) do |(file, todo)|
63
+ puts "* #{todo} (#{file})"
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,119 @@
1
+ module Libnotify
2
+ # API for Libnotify
3
+ #
4
+ # @see Libnotify
5
+ class API
6
+ include FFI
7
+
8
+ attr_reader :timeout, :icon_path
9
+ attr_accessor :summary, :body, :urgency, :append
10
+
11
+ class << self
12
+ # List of globs to icons
13
+ attr_accessor :icon_dirs
14
+ end
15
+
16
+ self.icon_dirs = [
17
+ "/usr/share/icons/gnome/*/emblems",
18
+ "/usr/share/icons/gnome/*/emotes"
19
+ ]
20
+
21
+ # TODO refactor & test!
22
+ ICON_REGEX = /(\d+)x\d/
23
+ ICON_SORTER = proc do |a, b|
24
+ ma = a.scan ICON_REGEX
25
+ mb = b.scan ICON_REGEX
26
+
27
+ if ma.first && mb.first
28
+ mb.first.first.to_i <=> ma.first.first.to_i
29
+ elsif ma.first && !mb.first
30
+ 1
31
+ elsif !ma.first && ma.first
32
+ -1
33
+ else
34
+ a <=> b
35
+ end
36
+ end
37
+
38
+ # Creates a notification object.
39
+ #
40
+ # @see Libnotify.new
41
+ def initialize(options={}, &block)
42
+ set_defaults
43
+ options.each { |key, value| send("#{key}=", value) if respond_to?(key) }
44
+ yield(self) if block_given?
45
+ end
46
+
47
+ def set_defaults
48
+ self.summary = self.body = ' '
49
+ self.urgency = :normal
50
+ self.timeout = nil
51
+ self.append = true
52
+ end
53
+ private :set_defaults
54
+
55
+ # Shows a notification.
56
+ #
57
+ # @see Libnotify.show
58
+ def show!
59
+ notify_init(self.class.to_s) or raise "notify_init failed"
60
+ notify = notify_notification_new(summary, body, icon_path, nil)
61
+ notify_notification_set_urgency(notify, lookup_urgency(urgency))
62
+ notify_notification_set_timeout(notify, timeout || -1)
63
+ if append
64
+ notify_notification_set_hint_string(notify, "x-canonical-append", "")
65
+ notify_notification_set_hint_string(notify, "append", "")
66
+ end
67
+ notify_notification_show(notify, nil)
68
+ ensure
69
+ notify_notification_clear_hints(notify) if append
70
+ end
71
+
72
+ # @todo Simplify timeout=
73
+ def timeout=(timeout)
74
+ @timeout = case timeout
75
+ when Float
76
+ timeout /= 10 if RUBY_VERSION == "1.8.6" # Strange workaround?
77
+ (timeout * 1000).to_i
78
+ when Fixnum
79
+ if timeout >= 100 # assume miliseconds
80
+ timeout
81
+ else
82
+ timeout * 1000
83
+ end
84
+ when NilClass, FalseClass
85
+ nil
86
+ else
87
+ timeout.to_s.to_i
88
+ end
89
+ end
90
+
91
+ # Sets icon path.
92
+ #
93
+ # Path can be absolute, relative (will be resolved) or an symbol.
94
+ #
95
+ # @todo document and refactor
96
+ def icon_path=(path)
97
+ case path
98
+ when /^\// # absolute
99
+ @icon_path = path
100
+ when String
101
+ list = self.class.icon_dirs.map { |d| Dir[File.join(d, path)] }.flatten.sort(&ICON_SORTER)
102
+ @icon_path = list.detect { |full_path| File.exist?(full_path) } || path
103
+ when Symbol
104
+ self.icon_path = "#{path}.png"
105
+ else
106
+ @icon_path = nil
107
+ end
108
+ end
109
+
110
+ # Creates and shows a notification. It's a shortcut for +Libnotify.new(options).show!+.
111
+ #
112
+ # @see Libnotify.show
113
+ # @see Libnotify.new
114
+ def self.show(options={}, &block)
115
+ new(options, &block).show!
116
+ end
117
+
118
+ end
119
+ end
@@ -0,0 +1,39 @@
1
+ module Libnotify
2
+ # Raw FFI bindings.
3
+ module FFI
4
+ require 'ffi'
5
+ extend ::FFI::Library
6
+
7
+ def self.included(base)
8
+ ffi_lib %w[libnotify libnotify.so libnotify.so.1]
9
+ attach_functions!
10
+ rescue LoadError => e
11
+ warn e.message
12
+ end
13
+
14
+ URGENCY = [ :low, :normal, :critical ]
15
+
16
+ def self.attach_functions!
17
+ attach_function :notify_init, [:string], :bool
18
+ attach_function :notify_uninit, [], :void
19
+ attach_function :notify_notification_new, [:string, :string, :string, :pointer], :pointer
20
+ attach_function :notify_notification_set_urgency, [:pointer, :int], :void
21
+ attach_function :notify_notification_set_timeout, [:pointer, :long], :void
22
+ attach_function :notify_notification_set_hint_string, [:pointer, :string, :string], :void
23
+ attach_function :notify_notification_clear_hints, [:pointer], :void
24
+ attach_function :notify_notification_show, [:pointer, :pointer], :bool
25
+ end
26
+
27
+ def lookup_urgency(urgency)
28
+ URGENCY.index(urgency)
29
+ end
30
+
31
+ def method_missing(method, *args, &block)
32
+ if method.to_s =~ /^notify_/
33
+ warn "libnotify.so not found!"
34
+ end
35
+
36
+ super
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module Libnotify
2
+ VERSION = "0.5.1"
3
+ end
data/lib/libnotify.rb ADDED
@@ -0,0 +1,58 @@
1
+ # Ruby bindings for libnotify using FFI.
2
+ #
3
+ # See README.rdoc for usage examples.
4
+ #
5
+ # @see README.rdoc
6
+ # @see Libnotify.new
7
+ # @author Peter Suschlik
8
+ module Libnotify
9
+ # Creates a notification.
10
+ #
11
+ # @example Block syntax
12
+ # n = Libnotify.new do |notify|
13
+ # notify.summary = "hello"
14
+ # notify.body = "world"
15
+ # notify.timeout = 1.5 # 1.5 (s), 1000 (ms), "2", nil, false
16
+ # notify.urgency = :critical # :low, :normal, :critical
17
+ # notify.append = false # default true - append onto existing notification
18
+ # notify.icon_path = "/usr/share/icons/gnome/scalable/emblems/emblem-default.svg"
19
+ # end
20
+ # n.show!
21
+ #
22
+ # @example Hash syntax
23
+ # Libnotify.show(:body => "hello", :summary => "world", :timeout => 2.5)
24
+ #
25
+ # @example Mixed syntax
26
+ # Libnotify.new(options) do |n|
27
+ # n.timeout = 1.5 # overrides :timeout in options
28
+ # n.show!
29
+ # end
30
+ #
31
+ # @param [Hash] options options creating a notification
32
+ # @option options [String] :summary (' ') summary/title of the notification
33
+ # @option options [String] :body (' ') the body
34
+ # @option options [Fixnum, Float, nil, FalseClass, String] :timeout (nil) display duration of the notification.
35
+ # Use +false+ or +nil+ for no timeout.
36
+ # @option options [Symbol] :urgency (:normal) the urgency of the notification.
37
+ # Possible values are: +:low+, +:normal+ and +:critical+
38
+ # @option options [String] :icon_path path the an icon displayed.
39
+ #
40
+ # @yield [notify] passes the notification object
41
+ # @yieldparam [API] notify the notification object
42
+ #
43
+ # @return [API] the notification object
44
+ def self.new(options={}, &block)
45
+ API.new(options, &block)
46
+ end
47
+
48
+ # Shows a notification. It takes the same +options+ as Libnotify.new.
49
+ #
50
+ # @see Libnotify.new
51
+ def self.show(options={}, &block)
52
+ API.show(options, &block)
53
+ end
54
+
55
+ autoload :VERSION, 'libnotify/version'
56
+ autoload :API, 'libnotify/api'
57
+ autoload :FFI, 'libnotify/ffi'
58
+ end
data/libnotify.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "libnotify"
4
+
5
+ platform = Gem::Platform::CURRENT
6
+ needs_ffi = true
7
+
8
+ if RUBY_PLATFORM =~ /java/
9
+ needs_ffi = false
10
+ elsif defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /rbx/
11
+ needs_ffi = false
12
+ platform = Gem::Platform::new ['universal', 'rubinius', '1.2']
13
+ end
14
+
15
+ Gem::Specification.new do |s|
16
+ s.name = "libnotify"
17
+ s.version = Libnotify::VERSION
18
+ s.platform = platform
19
+ s.authors = ["Peter Suschlik"]
20
+ s.email = ["peter-libnotify@suschlik.de"]
21
+ s.homepage = "http://rubygems.org/gems/libnotify"
22
+ s.summary = %q{Ruby bindings for libnotify using FFI}
23
+
24
+ s.files = `git ls-files`.split("\n")
25
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
26
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
27
+ s.require_paths = ["lib"]
28
+
29
+ if needs_ffi
30
+ s.add_runtime_dependency 'ffi', '~> 1.0'
31
+ end
32
+
33
+ s.add_development_dependency 'minitest'
34
+ s.add_development_dependency 'yard', '~> 0.7.0'
35
+ end
data/libnotify.png ADDED
Binary file
data/test/helper.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'minitest/autorun'
4
+
5
+ require 'libnotify'
6
+ require 'libnotify_io'
@@ -0,0 +1,36 @@
1
+ class LibnotifyIO
2
+ attr_reader :io, :libnotify
3
+
4
+ def initialize io
5
+ @io = io
6
+ @libnotify = begin
7
+ require 'libnotify'
8
+ Libnotify.new(:timeout => 2.5, :append => false)
9
+ end
10
+ end
11
+
12
+ def puts *o
13
+ if o.first =~ /(\d+) failures, (\d+) errors/
14
+ description = [ RUBY_ENGINE, RUBY_VERSION, RUBY_PLATFORM ].join(" ")
15
+ libnotify.body = o.first
16
+ if $1.to_i > 0 || $2.to_i > 0 # fail?
17
+ libnotify.summary = ":-( #{description}"
18
+ libnotify.urgency = :critical
19
+ libnotify.icon_path = "face-angry.*"
20
+ else
21
+ libnotify.summary += ":-) #{description}"
22
+ libnotify.urgency = :normal
23
+ libnotify.icon_path = "face-laugh.*"
24
+ end
25
+ libnotify.show!
26
+ else
27
+ io.puts *o
28
+ end
29
+ end
30
+
31
+ def method_missing msg, *args
32
+ io.send(msg, *args)
33
+ end
34
+ end
35
+
36
+ MiniTest::Unit.output = LibnotifyIO.new(MiniTest::Unit.output)
@@ -0,0 +1,109 @@
1
+ require 'helper'
2
+
3
+ class TestLibnotify < MiniTest::Unit::TestCase
4
+ def test_respond_to
5
+ assert_respond_to Libnotify, :new
6
+ assert_respond_to Libnotify, :show
7
+ end
8
+
9
+ def test_delegation
10
+ skip "test delegation using mock"
11
+
12
+ # old code
13
+ asserts("#new calls API#new") do
14
+ mock(Libnotify::API).new(hash_including(:body => "test")) { true }
15
+ Libnotify.new(:body => "test")
16
+ end
17
+ asserts("#show calls API#show") do
18
+ mock(Libnotify::API).show(hash_including(:body => "test")) { true }
19
+ Libnotify.show(:body => "test")
20
+ end
21
+ end
22
+
23
+ def test_version
24
+ assert defined?(Libnotify::VERSION), "version is defined"
25
+ assert Libnotify::VERSION
26
+ end
27
+ end
28
+
29
+ class TestLibnotifyAPI < MiniTest::Unit::TestCase
30
+ def test_without_options_and_block
31
+ assert_equal " ", libnotify.summary
32
+ assert_equal " ", libnotify.body
33
+ assert_equal :normal, libnotify.urgency
34
+ assert_nil libnotify.timeout
35
+ assert_nil libnotify.icon_path
36
+ assert libnotify.append
37
+ end
38
+
39
+ def test_with_options_and_block
40
+ libnotify(:summary => "hello", :body => "body", :invalid_option => 23) do |n|
41
+ n.body = "overwritten"
42
+ n.icon_path = "/path/to/icon"
43
+ n.append = false
44
+ end
45
+
46
+ assert_equal "hello", libnotify.summary
47
+ assert_equal "overwritten", libnotify.body
48
+ assert_equal "/path/to/icon", libnotify.icon_path
49
+ assert !libnotify.append
50
+ end
51
+
52
+ def test_timeout_setter
53
+ assert_timeout 2500, 2.5, "with float"
54
+ assert_timeout 100, 100, "with fixnum ms"
55
+ assert_timeout 101, 101, "with fixnum ms"
56
+ assert_timeout 1000, 1, "with fixnum seconds"
57
+ assert_timeout 99000, 99, "with fixnum seconds"
58
+ assert_timeout nil, nil, "with nil"
59
+ assert_timeout nil, false, "with false"
60
+ assert_timeout 2, :"2 s", "with to_s.to_i"
61
+ end
62
+
63
+ def test_icon_path_setter
64
+ Libnotify::API.icon_dirs << File.expand_path("../..", __FILE__)
65
+ assert_icon_path "/some/path/image.jpg", "/some/path/image.jpg", "with absolute path"
66
+ assert_icon_path "some-invalid-path.jpg", "some-invalid-path.jpg", "with non-existant relative path"
67
+ assert_icon_path %r{^/.*/libnotify.png}, "libnotify.png", "with relative path"
68
+ assert_icon_path %r{^/.*/libnotify.png}, :"libnotify", "with symbol"
69
+ end
70
+
71
+ def test_integration
72
+ skip "enable integration"
73
+
74
+ libnotify = Libnotify::API.new(:timeout => 0.5, :icon_path => :"emblem-favorite", :append => true)
75
+
76
+ [ :low, :normal, :critical ].each do |urgency|
77
+ libnotify.summary = "#{RUBY_VERSION} at #{RUBY_PLATFORM}"
78
+ libnotify.body = [ urgency, defined?(RUBY_DESCRIPTION) ? RUBY_DESCRIPTION : '?' ].join(" ")
79
+ libnotify.urgency = urgency
80
+ libnotify.show!
81
+ end
82
+ end
83
+
84
+ private
85
+
86
+ def libnotify(options={}, &block)
87
+ @libnotify ||= Libnotify::API.new(options, &block)
88
+ end
89
+
90
+ def assert_timeout(expected, value, message)
91
+ assert_value_set :timeout, expected, value, message
92
+ end
93
+
94
+ def assert_icon_path(expected, value, message)
95
+ assert_value_set :icon_path, expected, value, message
96
+ end
97
+
98
+ def assert_value_set(attribute, expected, value, message)
99
+ libnotify.send("#{attribute}=", value)
100
+ got = libnotify.send(attribute)
101
+ case expected
102
+ when Regexp
103
+ assert_match expected, got, message
104
+ else
105
+ assert_equal expected, got, message
106
+ end
107
+ end
108
+
109
+ end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: libnotify
3
+ version: !ruby/object:Gem::Version
4
+ hash: 9
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 5
9
+ - 1
10
+ version: 0.5.1
11
+ platform: universal-rubinius-1.2
12
+ authors:
13
+ - Peter Suschlik
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-05-19 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: minitest
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: yard
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ - 7
47
+ - 0
48
+ version: 0.7.0
49
+ type: :development
50
+ version_requirements: *id002
51
+ description:
52
+ email:
53
+ - peter-libnotify@suschlik.de
54
+ executables: []
55
+
56
+ extensions: []
57
+
58
+ extra_rdoc_files: []
59
+
60
+ files:
61
+ - .gitignore
62
+ - .rvmrc
63
+ - .travis.yml
64
+ - Gemfile
65
+ - README.rdoc
66
+ - Rakefile
67
+ - lib/libnotify.rb
68
+ - lib/libnotify/api.rb
69
+ - lib/libnotify/ffi.rb
70
+ - lib/libnotify/version.rb
71
+ - libnotify.gemspec
72
+ - libnotify.png
73
+ - test/helper.rb
74
+ - test/libnotify_io.rb
75
+ - test/test_libnotify.rb
76
+ has_rdoc: true
77
+ homepage: http://rubygems.org/gems/libnotify
78
+ licenses: []
79
+
80
+ post_install_message:
81
+ rdoc_options: []
82
+
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ hash: 3
91
+ segments:
92
+ - 0
93
+ version: "0"
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ hash: 3
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ requirements: []
104
+
105
+ rubyforge_project:
106
+ rubygems_version: 1.5.2
107
+ signing_key:
108
+ specification_version: 3
109
+ summary: Ruby bindings for libnotify using FFI
110
+ test_files: []
111
+