r_notify 0.0.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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 571eba555c6f048cff2ad01c0bad0a07ab5e05bd
4
+ data.tar.gz: 7e9d84eaa80b521117e6233cb3d4900e5be17fb0
5
+ SHA512:
6
+ metadata.gz: 248a15f3046aeae6a8fa284a7708f236a3a74b984ffee174723d125aec6f894ed697ae0cc23cca9f35b560852dda6cbff95c4bbc8685111641dd5f40968ac58d
7
+ data.tar.gz: 5ae05c4295d7b29563acab8387b5864df189c5aff5f67451ffc8c22f68d4666e2b872c2c6d6d270f634ae1d0258d933c022f32cf15499ff2faff6e68d1cde805
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rubote_notify.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Joakim Reinert
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,75 @@
1
+ # RNotify
2
+
3
+ RNotify is a notification library written in ruby. It consists of a server and client code which communicate with each other over drb.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'rubote_notify'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install rubote_notify
18
+
19
+ ## Usage
20
+
21
+ Start a server by running `rnotify-server`. You will be prompted for a password which clients will use to authenticate.
22
+
23
+ Start a client by running `rnotify-client`. You will again be prompted for a password which will be used to authenticate on the server. Any notifications sent to the server using its push method will be shown on the client.
24
+
25
+ Example chat program:
26
+
27
+ 1. Start a server
28
+ 2. Run following code on clients:
29
+
30
+ ``` ruby
31
+ require 'drb'
32
+
33
+ class ChatReader
34
+
35
+ def initialize(host, port, password)
36
+ @server = DRbObject.new_with_uri("druby://#{host}:#{port}")
37
+ @password = password
38
+ end
39
+
40
+ def start
41
+ loop do
42
+ message = @server.listen(@password)
43
+ puts message unless message == :heartbeat
44
+ end
45
+ end
46
+
47
+ end
48
+
49
+ class ChatWriter
50
+
51
+ def initialize(host, port, nick, password)
52
+ @server = DRbObject.new_with_uri("druby://#{host}:#{port}")
53
+ @nick = nick
54
+ @password = password
55
+ end
56
+
57
+ def start
58
+ loop do
59
+ print '> '
60
+ message = "#{@nick}: #{STDIN.gets.chomp}"
61
+ @server.push(@password, message)
62
+ end
63
+ end
64
+ end
65
+ ```
66
+
67
+ You get the picture...
68
+
69
+ ## Contributing
70
+
71
+ 1. Fork it
72
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
73
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
74
+ 4. Push to the branch (`git push origin my-new-feature`)
75
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'choice'
4
+ require 'highline/import'
5
+ require 'r_notify/client'
6
+
7
+ Choice.options do
8
+
9
+ header 'Options:'
10
+
11
+ option :action do
12
+ long '--action ACTION'
13
+ short '-a'
14
+ valid %w[start stop]
15
+ cast Symbol
16
+ default :start
17
+ desc 'Either start or stop (default: start)'
18
+ end
19
+
20
+ separator ''
21
+
22
+ option :host do
23
+ long '--host HOST'
24
+ short '-h'
25
+ desc 'The host of the notification server i.e. example.com. (default: localhost)'
26
+ default 'localhost'
27
+ end
28
+
29
+ option :port do
30
+ long '--port PORT'
31
+ short '-p'
32
+ cast Integer
33
+ desc 'The port the server is listening at. (default: 9000)'
34
+ default 9000
35
+ end
36
+
37
+ option :password do
38
+ long '--password PASSWORD'
39
+ short '-P'
40
+ desc 'The password for the notification server. If omitted it will be prompted for.'
41
+ end
42
+
43
+ option :daemon do
44
+ long '--daemon'
45
+ short '-d'
46
+ desc 'Run daemonized.'
47
+ end
48
+
49
+ end
50
+
51
+ pidfile = nil
52
+ if Choice[:action] == :stop || Choice[:daemon]
53
+ pidfile = File.join(ENV['HOME'], '.rnotify', 'client.pid')
54
+ if not Dir.exists?(File.dirname(pidfile))
55
+ FileUtils.mkdir_p(File.dirname(pidfile))
56
+ end
57
+ end
58
+
59
+ if Choice[:action] == :start
60
+ password = Choice[:password] || ask('Password: ') {|q| q.echo = '*'}
61
+ if Choice[:daemon]
62
+ pipe = IO.popen('-')
63
+ if pipe
64
+ File.open(pidfile, 'w+') do |file|
65
+ file.write(pipe.pid)
66
+ end
67
+ puts pipe.gets
68
+ exit
69
+ end
70
+ trap('HUP') { File.delete(pidfile) }
71
+ end
72
+ client = RNotify::Client.new("druby://#{Choice[:host]}:#{Choice[:port]}", password.to_s)
73
+ client.start
74
+ else
75
+ Process.kill('HUP', File.read(pidfile).to_i)
76
+ puts "Stopped notification client"
77
+ end
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'choice'
4
+ require 'highline/import'
5
+ require 'drb'
6
+ require 'r_notify/server'
7
+
8
+ Choice.options do
9
+
10
+ header ''
11
+
12
+ option :action do
13
+ long '--action ACTION'
14
+ short '-a'
15
+ valid %w[start stop]
16
+ cast Symbol
17
+ default :start
18
+ desc 'Either start or stop (default: start). Required.'
19
+ end
20
+
21
+ separator ''
22
+
23
+ option :port do
24
+ long '--port PORT'
25
+ short '-p'
26
+ cast Integer
27
+ desc 'The port to listen at. (default: 9000)'
28
+ default 9000
29
+ end
30
+
31
+ option :password do
32
+ long '--password PASSWORD'
33
+ short '-P'
34
+ desc 'The password which clients will use to authenticate. If omitted it will be prompted for.'
35
+ end
36
+
37
+ option :daemon do
38
+ long '--daemon'
39
+ short '-d'
40
+ desc 'Run daemonized.'
41
+ end
42
+
43
+ option :help do
44
+ long '--help'
45
+ desc 'Show this message'
46
+ end
47
+
48
+ end
49
+
50
+ pidfile = nil
51
+ if Choice[:action] == :stop || Choice[:daemon]
52
+ pidfile = File.join(ENV['HOME'], '.rnotify', 'server.pid')
53
+ if not Dir.exists?(File.dirname(pidfile))
54
+ FileUtils.mkdir_p(File.dirname(pidfile))
55
+ end
56
+ end
57
+
58
+ if Choice[:action] == :start
59
+ password = Choice[:password] || ask('Password: ') {|q| q.echo = '*'}
60
+ if Choice[:daemon]
61
+ pipe = IO.popen('-')
62
+ if pipe
63
+ File.open(pidfile, 'w+') do |file|
64
+ file.write(pipe.pid)
65
+ end
66
+ puts pipe.gets
67
+ exit
68
+ end
69
+ trap('HUP') { File.delete(pidfile) }
70
+ end
71
+ DRb.start_service("druby://:#{Choice[:port]}", RNotify::Server.new(password.to_s))
72
+ puts "Started notification server at #{DRb.uri}"
73
+ DRb.thread.join
74
+ else
75
+ Process.kill('HUP', File.read(pidfile).to_i)
76
+ puts "Stopped notification server"
77
+ end
@@ -0,0 +1,46 @@
1
+ require 'drb'
2
+ require 'highline/import'
3
+ require 'choice'
4
+
5
+ Choice.options do
6
+
7
+ option :host do
8
+ long '--host HOST'
9
+ short '-h'
10
+ default 'localhost'
11
+ end
12
+
13
+ option :port do
14
+ long '--port PORT'
15
+ short '-p'
16
+ cast Integer
17
+ default 9000
18
+ end
19
+
20
+ option :password do
21
+ long '--passwort PASSWORD'
22
+ short '-P'
23
+ end
24
+
25
+ end
26
+
27
+ class ChatReader
28
+
29
+ def initialize(host, port, password)
30
+ @server = DRbObject.new_with_uri("druby://#{host}:#{port}")
31
+ @password = password
32
+ end
33
+
34
+ def start
35
+ loop do
36
+ message = @server.listen(@password)
37
+ puts message unless message == :heartbeat
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ password = Choice[:password] || ask('Password: ') {|q| q.echo = '*'}
44
+ reader = ChatReader.new(Choice[:host], Choice[:port], password)
45
+ trap('INT') { exit }
46
+ reader.start
@@ -0,0 +1,68 @@
1
+ require 'drb'
2
+ require 'highline/import'
3
+ require 'choice'
4
+
5
+ Choice.options do
6
+
7
+ option :host do
8
+ long '--host HOST'
9
+ short '-h'
10
+ default 'localhost'
11
+ end
12
+
13
+ option :port do
14
+ long '--port PORT'
15
+ short '-p'
16
+ cast Integer
17
+ default 9000
18
+ end
19
+
20
+ option :nick do
21
+ long '--nick NICK'
22
+ short '-n'
23
+ end
24
+
25
+ option :password do
26
+ long '--password PASSWORD'
27
+ short '-P'
28
+ end
29
+
30
+ end
31
+
32
+ class ChatWriter
33
+
34
+ def initialize(host, port, nick, password)
35
+ @server = DRbObject.new_with_uri("druby://#{host}:#{port}")
36
+ @nick = nick
37
+ @password = password
38
+ end
39
+
40
+ def start
41
+ @thread = Thread.new do
42
+ send("#{@nick} joined the room")
43
+ loop do
44
+ print '> '
45
+ message = "#{@nick}: #{STDIN.gets.chomp}"
46
+ send(message)
47
+ end
48
+ end
49
+ end
50
+
51
+ def send(message)
52
+ @server.push(@password, "#{Time.now.strftime('%H:%M:%S GMT%:::z')} | #{message}")
53
+ end
54
+
55
+ def quit
56
+ @thread.kill
57
+ send("#{@nick} left the room")
58
+ end
59
+ end
60
+
61
+ nick = Choice[:nick] || ask('Nick: ')
62
+ password = Choice[:password] || ask('Password: ') { |q| q.echo = '*' }
63
+ writer = ChatWriter.new(Choice[:host], Choice[:port], nick, password)
64
+ begin
65
+ writer.start.join
66
+ rescue Interrupt
67
+ writer.quit
68
+ end
@@ -0,0 +1,6 @@
1
+ require "r_notify/version"
2
+ require "r_notify/server"
3
+ require "r_notify/client"
4
+
5
+ module RNotify
6
+ end
@@ -0,0 +1,37 @@
1
+ module RNotify
2
+ class Client
3
+ require 'gir_ffi'
4
+ require "drb"
5
+
6
+ def initialize(server_uri, password)
7
+ @server_uri = server_uri
8
+ @server = DRbObject.new_with_uri(@server_uri)
9
+ @password = password
10
+ GirFFI.setup :Notify
11
+ Notify.init("Rubote notify")
12
+ end
13
+
14
+ def start
15
+ puts "Listening for notifications from #{@server_uri}"
16
+ loop do
17
+ message = @server.listen(@password)
18
+ next if message == :heartbeat
19
+ notification(message).show
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def notification message
26
+ buffer = message[:buffer]
27
+ prefix = message[:prefix]
28
+ message = message[:message]
29
+ Notify::Notification.new(
30
+ "<i>#{buffer || "Query"}:</i>",
31
+ "<b>#{prefix}</b> | #{message}",
32
+ "dialog-information"
33
+ )
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,35 @@
1
+ module RNotify
2
+ class Server
3
+
4
+ def initialize(password)
5
+ @notification_queue = Queue.new
6
+ @password = password
7
+ Thread.new do
8
+ loop do
9
+ push(:heartbeat)
10
+ sleep 30
11
+ end
12
+ end
13
+ end
14
+
15
+ def listen(password)
16
+ authenticate password
17
+ @notification_queue.pop
18
+ end
19
+
20
+ def push(password, notification)
21
+ authenticate password
22
+ @notification_queue.push(notification)
23
+ end
24
+
25
+ class AuthError < SecurityError; end
26
+
27
+ private
28
+
29
+ def authenticate(password)
30
+ sleep 1 # slow down brute forcing
31
+ raise AuthError unless password == @password
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module RNotify
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'r_notify/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "r_notify"
8
+ spec.version = RNotify::VERSION
9
+ spec.authors = ["Joakim Reinert"]
10
+ spec.email = ["mail@jreinert.com"]
11
+ spec.description = %q{r_notify is a notification library using drb.}
12
+ spec.summary = %q{r_notify consists of a server and a client. Multiple clients can connect to a server and exchange notifications.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+
24
+ spec.add_dependency "highline"
25
+ spec.add_dependency "choice"
26
+ spec.add_dependency "gir_ffi"
27
+
28
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: r_notify
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Joakim Reinert
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: highline
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: choice
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'
69
+ - !ruby/object:Gem::Dependency
70
+ name: gir_ffi
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: r_notify is a notification library using drb.
84
+ email:
85
+ - mail@jreinert.com
86
+ executables:
87
+ - rnotify-client
88
+ - rnotify-server
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - .gitignore
93
+ - Gemfile
94
+ - LICENSE.txt
95
+ - README.md
96
+ - Rakefile
97
+ - bin/rnotify-client
98
+ - bin/rnotify-server
99
+ - examples/chat_reader.rb
100
+ - examples/chat_writer.rb
101
+ - lib/r_notify.rb
102
+ - lib/r_notify/client.rb
103
+ - lib/r_notify/server.rb
104
+ - lib/r_notify/version.rb
105
+ - r_notify.gemspec
106
+ homepage: ''
107
+ licenses:
108
+ - MIT
109
+ metadata: {}
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 2.0.6
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: r_notify consists of a server and a client. Multiple clients can connect
130
+ to a server and exchange notifications.
131
+ test_files: []