dock_driver 0.1.0

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/.autotest ADDED
@@ -0,0 +1,23 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'autotest/restart'
4
+
5
+ # Autotest.add_hook :initialize do |at|
6
+ # at.extra_files << "../some/external/dependency.rb"
7
+ #
8
+ # at.libs << ":../some/external"
9
+ #
10
+ # at.add_exception 'vendor'
11
+ #
12
+ # at.add_mapping(/dependency.rb/) do |f, _|
13
+ # at.files_matching(/test_.*rb$/)
14
+ # end
15
+ #
16
+ # %w(TestA TestB).each do |klass|
17
+ # at.extra_class_map[klass] = "test/test_misc.rb"
18
+ # end
19
+ # end
20
+
21
+ # Autotest.add_hook :run_command do |at|
22
+ # system "rake build"
23
+ # end
data/.gemtest ADDED
File without changes
data/.hgignore ADDED
@@ -0,0 +1,2 @@
1
+ doc/.*
2
+ pkg/.*
data/History.txt ADDED
@@ -0,0 +1,26 @@
1
+ === 0.1.0 / 2012-05-15
2
+
3
+ * 3 minor enhancements
4
+
5
+ * bin/dock_driver completed
6
+ * RSpec tests completed & passing
7
+ * Several bugs fixed
8
+
9
+ === 0.0.3 / 2012-05-15
10
+
11
+ * 1 minor enhancement
12
+
13
+ * Doc & Manifest Updates
14
+
15
+ === 0.0.2 / 2012-05-15
16
+
17
+ * 1 minor enhancement
18
+
19
+ * 100% documentation coverage
20
+
21
+ === 0.0.1 / 2012-05-15
22
+
23
+ * 1 major enhancement
24
+
25
+ * Birthday!
26
+
data/Ideas.txt ADDED
@@ -0,0 +1,20 @@
1
+ = Ideas
2
+
3
+ == Without Dependencies
4
+
5
+ * Graphing
6
+ * Automatic Coloring (with definable syntax)
7
+ * Logging
8
+
9
+ == With Dependencies
10
+
11
+ * Maildir support
12
+ * SNMP Poller
13
+ * gateway / internet latency
14
+
15
+ == dzen2 Ideas
16
+
17
+ * buttons
18
+ * events
19
+ * text window
20
+
data/Manifest.txt ADDED
@@ -0,0 +1,17 @@
1
+ .autotest
2
+ .hgignore
3
+ History.txt
4
+ Ideas.txt
5
+ Manifest.txt
6
+ README.txt
7
+ Rakefile
8
+ bin/dock_driver
9
+ data/example.dock_driver.yml
10
+ lib/dock_driver.rb
11
+ lib/dock_driver/laika_hashutils.rb
12
+ lib/dock_driver/poll.rb
13
+ lib/dock_driver/data_rate_poll.rb
14
+ lib/dock_driver/dock.rb
15
+ spec/dock_driver/dock_spec.rb
16
+ spec/dock_driver/poll_spec.rb
17
+ spec/dock_driver_spec.rb
data/README.txt ADDED
@@ -0,0 +1,74 @@
1
+ = dock_driver
2
+
3
+ * http://hg.musl.org/projects/dock_driver/
4
+
5
+ == DESCRIPTION:
6
+
7
+ Provides a simple executable to drive a dzen2 (or similar) dock with a
8
+ single YAML config file.
9
+
10
+ Read +example.dock_driver.yml+ for more information about how to get
11
+ started. It's located in this gem's data directory, which is usually:
12
+ $GEM_HOME/gems/dock_driver-x.y.z/data/
13
+
14
+ == FEATURES/PROBLEMS:
15
+
16
+ === Features:
17
+
18
+ * easy, flexible configuration
19
+ * field extraction with +scan_regex+ (no grep or pipes necessary)
20
+
21
+ === Problems:
22
+
23
+ * undiscovered bugs
24
+ * unwritten test cases
25
+ * cleanup
26
+
27
+ == SYNOPSIS:
28
+
29
+ There really isn't an API or interface other than the YAML config file.
30
+
31
+ == REQUIREMENTS:
32
+
33
+ * This gem proudly has zero dependencies besides ruby and rubygems.
34
+
35
+ == INSTALL:
36
+
37
+ * sudo gem install dock_driver
38
+ * copy <gemdir>/etc/example.dock_driver.yml to ~/.dock_driver.yml
39
+ * edit ~/.dock_driver.yml to taste
40
+ * run dock_driver from your xsession or ~/.i3/config file.
41
+
42
+ == DEVELOPERS:
43
+
44
+ After checking out the source, run:
45
+
46
+ $ rake newb
47
+
48
+ This task will install any missing dependencies, run the tests/specs,
49
+ and generate the RDoc.
50
+
51
+ == LICENSE:
52
+
53
+ (The MIT License)
54
+
55
+ Copyright (c) 2012 Michael Hix
56
+
57
+ Permission is hereby granted, free of charge, to any person obtaining
58
+ a copy of this software and associated documentation files (the
59
+ 'Software'), to deal in the Software without restriction, including
60
+ without limitation the rights to use, copy, modify, merge, publish,
61
+ distribute, sublicense, and/or sell copies of the Software, and to
62
+ permit persons to whom the Software is furnished to do so, subject to
63
+ the following conditions:
64
+
65
+ The above copyright notice and this permission notice shall be included
66
+ in all copies or substantial portions of the Software.
67
+
68
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
69
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
70
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
71
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
72
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
73
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
74
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+
2
+ require 'rubygems'
3
+ require 'hoe'
4
+
5
+ Hoe.plugin :mercurial
6
+
7
+ Hoe.spec 'dock_driver' do
8
+ developer 'Michael Hix', 'mike@musl.org'
9
+ require_ruby_version '>= 1.8.7'
10
+ require_rubygems_version '>= 1.8'
11
+ end
12
+
data/bin/dock_driver ADDED
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'dock_driver/dock'
5
+
6
+ include Signal
7
+
8
+ opts = {}
9
+ parser = OptionParser.new do |p|
10
+
11
+ p.on(
12
+ '-c',
13
+ '--conf FILE',
14
+ 'Specify an alternate config file. (Default: ~/.dock_driver.yml)'
15
+ ) do |file|
16
+ opts[:conf] = file
17
+ end
18
+
19
+ p.on(
20
+ '-d',
21
+ '--dock COMMAND',
22
+ 'Override the dock command from the config file.'
23
+ ) do |command|
24
+ opts[:dock] = command
25
+ end
26
+
27
+ p.on( '-e', '--debug', 'Enable $DEBUG' ) { |debug| $DEBUG = true }
28
+
29
+ p.on( '-h', '--help', 'Print this help text.' ) do
30
+ cmd = File.basename( $0 )
31
+ puts "\n%s\n%s\n\nVersion: %s\n%s\n\n" % [
32
+ cmd,
33
+ '=' * cmd.length,
34
+ DockDriver::VERSION,
35
+ DockDriver::REVISION,
36
+ ]
37
+ puts p
38
+ puts "\nAuthors:\n\t%s\n\n" % [
39
+ DockDriver::AUTHORS.join( '\n\t' ),
40
+ ]
41
+ exit
42
+ end
43
+
44
+ end.parse!
45
+
46
+ puts "Options: %p" % opts if $DEBUG
47
+
48
+ dock = DockDriver::Dock.new( opts[:conf], opts[:dock] )
49
+
50
+ trap 'INT' do
51
+ dock.kill
52
+ puts "\nKilled!" if $DEBUG
53
+ end
54
+
55
+ dock.run
56
+
@@ -0,0 +1,80 @@
1
+ ---
2
+ # Specify a program to run here. This bit of code was initially meant to run
3
+ # dzen2 but other docks are certainly appropriate, provided they accept commands
4
+ # and data over standard input. You'll probably need to adjust your formats and
5
+ # templates below if you use a different dock program.
6
+ #
7
+ dock_command:
8
+ dzen2 -dock -ta r -x 0 -y 0 -w 1680 -h 24 -bg black -fg white
9
+ -fn "-*-terminus-medium-r-*-*-12-*-*-*-*-*-*-*"
10
+ -e "button3="
11
+
12
+ # See the manpages for strftime and dzen2.
13
+ #
14
+ time_format:
15
+ ^fg(white)%A ^fg(gray80)%Y-%m-%d ^fg(gray60)%H:%M:%S ^fg(gray30)%Z
16
+
17
+ # Determines the layout and styling of the dock.
18
+ #
19
+ # Processed by +ERB+. +Poll+ objects as defined by the 'commands' section are
20
+ # available. Since +Poll+ objects respond to to_s intelligently, it's usually
21
+ # sufficient to just specify the object name. Since they're also subclasses of
22
+ # +OpenStruct+, you can also reference any method or member here.
23
+ #
24
+ # See the dzen2 documentation.
25
+ #
26
+ template:
27
+ ^fg(white)rx ^fg(gray60)<%= eth0_rx %> ^fg(gray30)<%= eth0_rx.unit %> ·
28
+ ^fg(white)tx ^fg(gray60)<%= eth0_tx %> ^fg(gray30)<%= eth0_tx.unit %> ·
29
+ ^fg(white)cpu0 ^fg(gray60)<%= cpu0_temp %>^fg(gray30) C ·
30
+ ^fg(white)cpu1 ^fg(gray60)<%= cpu1_temp %>^fg(gray30) C ·
31
+ ^fg(white)gpu ^fg(gray60)<%= gpu_temp %>^fg(gray30) C ·
32
+ ^fg(white)mail <%= mail %>^fg(gray30) ·
33
+ ^fg(gray60)<%= time %>^fg(gray30) ·
34
+
35
+ # Commands to poll. Each command will be polled every second, but specifying a
36
+ # +delay+ greater than one will cache the value and only run the command every
37
+ # +delay+ seconds. This defaults to evaluating a string with a shell, but if
38
+ # your YAML fu is strong enough, you can specify a Proc here too.
39
+ #
40
+ # To narrow down the output, you may use +scan_regex+. A single-quoted regex
41
+ # without forward slashes works great. Since scan returns an array, using one
42
+ # or more capture groups will allow you to pull multiple values from a single
43
+ # command's output - the values returned will be joined with single spaces.
44
+ #
45
+ # To change the class used to poll the command, you can specify a +type+.
46
+ # Right now, only 'rate' is recognized. It uses a separate class that expects
47
+ # a string containing a single number. Best to use +scan_regex+ here. It
48
+ # calculates a running average based on the changes in the value over time.
49
+ # A unit of measurement (b, kb, mb, gb, tb, pb, eb, zb, yb) or its full name
50
+ # (bits, kibibits, mebibits, ...) is also useful here. You may also specify a
51
+ # +number_format+ here if you don't like the default. See +sprintf+ for details
52
+ # on the format string.
53
+ #
54
+ commands:
55
+ mail:
56
+ cmd: '/home/joeuser/bin/dockmail'
57
+ delay: 5
58
+ cpu0_temp:
59
+ cmd: 'sensors'
60
+ scan_regex: 'Core 0:\s+\+(\d+\.\d+)'
61
+ delay: 30
62
+ cpu1_temp:
63
+ cmd: 'sensors'
64
+ scan_regex: 'Core 1:\s+\+(\d+\.\d+)'
65
+ delay: 30
66
+ gpu_temp:
67
+ cmd: 'nvidia-smi -q -d TEMPERATURE'
68
+ scan_regex: '(\d+) C'
69
+ delay: 30
70
+ eth0_rx:
71
+ cmd: 'ifconfig eth0'
72
+ scan_regex: 'RX bytes:(\d+)'
73
+ type: rate
74
+ unit: mb
75
+ eth0_tx:
76
+ cmd: 'ifconfig eth0'
77
+ scan_regex: 'TX bytes:(\d+)'
78
+ type: rate
79
+ unit: mb
80
+
@@ -0,0 +1,141 @@
1
+
2
+ require 'ostruct'
3
+
4
+ require 'dock_driver' unless defined? DockDriver
5
+ require 'dock_driver/poll'
6
+
7
+ # A class to provide simple, periodic command execution, caching, and a
8
+ # running average in changes in a value.
9
+ #
10
+ class DockDriver::DataRatePoll < DockDriver::Poll
11
+
12
+ # Default values to populate the OpenStruct with.
13
+ #
14
+ DEFAULTS = {
15
+ :unit => :mb,
16
+ :history_size => 2,
17
+ :number_format => '%0.3f',
18
+ }.freeze
19
+
20
+ # Create a new DataRatePoll.
21
+ #
22
+ # === Arguments:
23
+ #
24
+ # +opts+ - A hash containing options. Merged with DEFAULTS.
25
+ #
26
+ # +block+ - If a block is given, replace :cmd with that block.
27
+ #
28
+ # === Options:
29
+ #
30
+ # +:delay+ - Determines the minimum amount of time to let elapse between executions.
31
+ #
32
+ # +:cmd+ - A string or block to execute.
33
+ #
34
+ # +:scan_regex+ - A bare string to be interpreted as a regex for use with +scan+. Any
35
+ # capture group matches will be joined with single spaces.
36
+ #
37
+ # +:history_size+ - How many samples to keep
38
+ #
39
+ # +:unit+ - The unit to use. See the methods and aliases available.
40
+ # (b, kb, mb, gb, tb, pb, eb, zb, yb, and full names: bits, kibibits, mebibits, ...)
41
+ #
42
+ # +:number_format+ - The format used by +to_s+ to turn a number into a string. See: +printf+
43
+ #
44
+ def initialize( opts = {} )
45
+ super DEFAULTS.merge( opts )
46
+
47
+ @last_sample = nil
48
+ @history = Array.new( @table[:history_size] ) { 0 }
49
+ @average = 0
50
+ end
51
+
52
+ # Runs the command if enough time has elapsed since the last
53
+ # poll. "Enough Time" is defined by the :delay option. Maintains the
54
+ # history of output, average and formatting.
55
+ #
56
+ def poll
57
+ return false unless super
58
+
59
+ @sample = @sample.to_s.to_f unless @sample.is_a? Float
60
+ @last_sample ||= @sample
61
+ sample = 8 * ( @sample - @last_sample )
62
+ @history.shift if @history.length >= @table[:history_size]
63
+ @history.push sample
64
+ @last_sample = @sample
65
+ @average = @table[:number_format] % send( @table[:unit] )
66
+
67
+ true
68
+ end
69
+
70
+ # Returns the average value in bits.
71
+ #
72
+ def bits
73
+ @history.inject( :+ ) / @history.count.to_f
74
+ end
75
+ alias :b :bits
76
+
77
+ # Returns the average value in kibibits.
78
+ #
79
+ def kibibits
80
+ bits / 1024.0
81
+ end
82
+ alias :kb :kibibits
83
+
84
+ # Returns the average value in mebibits.
85
+ #
86
+ def mebibits
87
+ kibibits / 1024.0
88
+ end
89
+ alias :mb :mebibits
90
+
91
+ # Returns the average value in gibibits.
92
+ #
93
+ def gibibits
94
+ mebibits / 1024.0
95
+ end
96
+ alias :gb :gibibits
97
+
98
+ # Returns the average value in tebibits.
99
+ #
100
+ def tebibits
101
+ gibibits / 1024.0
102
+ end
103
+ alias :tb :tebibits
104
+
105
+ # Returns the average value in pebibits.
106
+ #
107
+ def pebibits
108
+ tebibits / 1024.0
109
+ end
110
+ alias :pb :pebibits
111
+
112
+ # Returns the average value in exbibits.
113
+ #
114
+ def exbibits
115
+ pebibits / 1024.0
116
+ end
117
+ alias :eb :exbibits
118
+
119
+ # Returns the average value in zebibits.
120
+ #
121
+ def zebibits
122
+ exbibits / 1024.0
123
+ end
124
+ alias :zb :zebibits
125
+
126
+ # Returns the average value in yobibits.
127
+ #
128
+ def yobibits
129
+ zebibits / 1024.0
130
+ end
131
+ alias :yb :yobibits
132
+
133
+ # Returns the output of the command this Poll runs, formated as per the
134
+ # option :number_format.
135
+ #
136
+ def to_s
137
+ @average
138
+ end
139
+
140
+ end
141
+
@@ -0,0 +1,126 @@
1
+
2
+ require 'erb'
3
+ require 'yaml'
4
+ require 'ostruct'
5
+
6
+ require 'dock_driver' unless defined? DockDriver
7
+ require 'dock_driver/laika_hashutils'
8
+ require 'dock_driver/poll'
9
+ require 'dock_driver/data_rate_poll'
10
+
11
+ # An object that represents and drives a dock program, periodically
12
+ # updating what it displays.
13
+ #
14
+ class DockDriver::Dock < OpenStruct
15
+
16
+ include LAIKA::HashUtilities
17
+
18
+ # Default values to populate this OpenStruct with.
19
+ #
20
+ DEFAULTS = {
21
+ :polls => {},
22
+ :time_format => '%Y-%m-%d %H:%M:%S %Z',
23
+ :config_file => File.expand_path( '~/.dock_driver.yml' ),
24
+ :template => '',
25
+ }.freeze
26
+
27
+ # Create and start a new Dock.
28
+ #
29
+ # === Arguments:
30
+ #
31
+ # +:config_file+ - Provide a path to a config file different from
32
+ # the default: ~/.dock_driver.yml
33
+ #
34
+ # +:dock_command+ - Override the dock command from the config file.
35
+ #
36
+ def initialize( config_file = nil, dock_command = nil )
37
+ super DEFAULTS
38
+ @worker = nil
39
+ @table[:config_file] = config_file if config_file
40
+ load_config
41
+ @table[:dock_command] = dock_command if dock_command
42
+ end
43
+
44
+ # Returns the result of the template.
45
+ #
46
+ def to_s()
47
+ # Poll everything.
48
+ @table[:polls].values.map( &:poll )
49
+
50
+ # Prepare a binding and render the ERB template.
51
+ vbind = OpenStruct.new( @table[:polls] ).send( :binding )
52
+ @table[:template].result( vbind ).gsub( /\s+/, ' ' )
53
+ end
54
+
55
+ # Start thiis Dock if it isn't already running, does nothing otherwise.
56
+ #
57
+ def run
58
+ @worker ||= Thread.new do
59
+ while true
60
+ File.popen( @table[:dock_command], 'w' ) do |pipe|
61
+ while true
62
+ pipe.puts self
63
+ pipe.flush
64
+ sleep 1
65
+ break if load_config
66
+ end
67
+ end
68
+ end
69
+ end
70
+ @worker.run unless @worker.status
71
+ @worker.join
72
+ end
73
+
74
+ # Forcibly stops this Dock if it is running, does nothing otherwise.
75
+ #
76
+ def kill
77
+ @worker.kill if @worker.status
78
+ end
79
+
80
+ #########
81
+ protected
82
+ #########
83
+
84
+ # Loads the configuration file defined by the option +:config_file+ if it has
85
+ # changed since this method was last called. If not, returns false.
86
+ #
87
+ # === Arguments:
88
+ #
89
+ # +force+ - If true, force a reload, even if the config file hasn't changed.
90
+ #
91
+ def load_config( force = false )
92
+
93
+ mtime = File.mtime @table[:config_file]
94
+ return false if not force and mtime == @table[:config_mtime]
95
+
96
+ @table.delete :template
97
+ hash = symbolify_keys( YAML.load_file( @table[:config_file] ) )
98
+ hash.delete :config_file
99
+ @table.merge! hash
100
+ @table[:config_mtime] = mtime
101
+
102
+ @table[:polls] = {}
103
+
104
+ if @table[:commands] and @table[:commands].is_a? Hash
105
+ @table[:commands].each do |name,hash|
106
+ klass = DockDriver::Poll
107
+ case hash[:type]
108
+ when /rate/i
109
+ klass = DockDriver::DataRatePoll
110
+ end
111
+ @table[:polls][name] = klass.new( hash )
112
+ end
113
+ end
114
+
115
+ if @table[:polls]['time'].nil?
116
+ @table[:polls]['time'] = DockDriver::Poll.new( { :delay => 1 } ) do
117
+ Time.now.strftime( @table[:time_format] )
118
+ end
119
+ end
120
+
121
+ @table[:template] = ERB.new( @table[:template] )
122
+
123
+ return true
124
+ end
125
+
126
+ end
@@ -0,0 +1,74 @@
1
+ # A module borrowed from my coworkers at LAIKA.
2
+ #
3
+ module LAIKA
4
+
5
+ ### A collection of utilities for working with Hashes.
6
+ module HashUtilities
7
+
8
+ ###############
9
+ module_function
10
+ ###############
11
+
12
+ ### Return a version of the given +hash+ with its keys transformed
13
+ ### into Strings from whatever they were before.
14
+ def stringify_keys( hash )
15
+ newhash = {}
16
+
17
+ hash.each do |key,val|
18
+ if val.is_a?( Hash )
19
+ newhash[ key.to_s ] = stringify_keys( val )
20
+ else
21
+ newhash[ key.to_s ] = val
22
+ end
23
+ end
24
+
25
+ return newhash
26
+ end
27
+
28
+
29
+ ### Return a duplicate of the given +hash+ with its identifier-like keys
30
+ ### transformed into symbols from whatever they were before.
31
+ def symbolify_keys( hash )
32
+ newhash = {}
33
+
34
+ hash.each do |key,val|
35
+ keysym = key.to_s.dup.untaint.to_sym
36
+
37
+ if val.is_a?( Hash )
38
+ newhash[ keysym ] = symbolify_keys( val )
39
+ else
40
+ newhash[ keysym ] = val
41
+ end
42
+ end
43
+
44
+ return newhash
45
+ end
46
+ alias_method :internify_keys, :symbolify_keys
47
+
48
+
49
+ # Recursive hash-merge function
50
+ def merge_recursively( key, oldval, newval )
51
+ case oldval
52
+ when Hash
53
+ case newval
54
+ when Hash
55
+ oldval.merge( newval, &method(:merge_recursively) )
56
+ else
57
+ newval
58
+ end
59
+
60
+ when Array
61
+ case newval
62
+ when Array
63
+ oldval | newval
64
+ else
65
+ newval
66
+ end
67
+
68
+ else
69
+ newval
70
+ end
71
+ end
72
+
73
+ end # HashUtilities
74
+ end
@@ -0,0 +1,72 @@
1
+
2
+ require 'ostruct'
3
+
4
+ require 'dock_driver' unless defined? DockDriver
5
+
6
+ # A class to provide simple, periodic command execution and caching.
7
+ #
8
+ class DockDriver::Poll < OpenStruct
9
+
10
+ # Default values to populate the OpenStruct with.
11
+ #
12
+ DEFAULTS = {
13
+ :delay => 1,
14
+ }.freeze
15
+
16
+ # Create a new Poll.
17
+ #
18
+ # === Arguments:
19
+ #
20
+ # +opts+ - A hash containing options. Merged with DEFAULTS.
21
+ #
22
+ # +block+ - If a block is given, replace :cmd with that block.
23
+ #
24
+ # === Options:
25
+ #
26
+ # +:delay+ - Determines the minimum amount of time to let elapse between executions.
27
+ #
28
+ # +:cmd+ - A string or block to execute.
29
+ #
30
+ # +:scan_regex+ - A bare string to be interpreted as a regex for use with +scan+. Any
31
+ # capture group matches will be joined with single spaces.
32
+ #
33
+ def initialize( opts = {}, &block )
34
+ super DEFAULTS.merge( opts )
35
+ @sample = nil
36
+
37
+ if block_given?
38
+ @table[:cmd] = block
39
+ end
40
+ end
41
+
42
+ # Runs the command if enough time has elapsed since the last poll. "Enough Time" is
43
+ # defined by the :delay option.
44
+ #
45
+ def poll
46
+ return false if @sample and (Time.now - (@table[:last_poll] || 0 )) < @table[:delay]
47
+
48
+ @table[:last_poll] = Time.now
49
+
50
+ case @table[:cmd]
51
+ when Proc
52
+ @sample = @table[:cmd].call
53
+ else
54
+ @sample = `#{@table[:cmd].to_s}`
55
+ end
56
+
57
+ if @table[:scan_regex]
58
+ extract = @sample.scan( Regexp.new( @table[:scan_regex] ) ).flatten
59
+ @sample = extract.join( ' ' ) unless extract.empty?
60
+ end
61
+
62
+ true
63
+ end
64
+
65
+ # Returns the output of the command this Poll runs.
66
+ #
67
+ def to_s
68
+ @sample
69
+ end
70
+
71
+ end
72
+
@@ -0,0 +1,16 @@
1
+
2
+ # A namespace for the project.
3
+ #
4
+ module DockDriver
5
+
6
+ # Version Constant
7
+ VERSION = '0.1.0'
8
+
9
+ # Revision Constant
10
+ REVISION = %q$Revision: d17549778789 $
11
+
12
+ # Behold the author(s) responsible for this mess.
13
+ AUTHORS = [ 'Mike Hix <mike@musl.org>' ]
14
+
15
+ end
16
+
@@ -0,0 +1,40 @@
1
+
2
+ require 'pathname'
3
+ require 'fileutils'
4
+ require 'dock_driver/dock'
5
+
6
+ describe DockDriver::Dock do
7
+
8
+ subject do
9
+ conf = Pathname( __FILE__ ).parent.parent.parent + 'data'
10
+ conf += 'example.dock_driver.yml'
11
+ dock = Dock.new conf, 'cat'
12
+ dock
13
+ end
14
+
15
+ it 'should be able to load a config file properly' do
16
+ subject.dock_command.should_not be nil
17
+ subject.template.should_not be nil
18
+ subject.polls.should have_at_least( 2 ).things
19
+ subject.polls.values.each { |p| p.should be_a_kind_of Poll }
20
+ end
21
+
22
+ it 'should only attempt to reload a config file with a more recent mtime' do
23
+ subject.send( :load_config ).should be false
24
+ FileUtils.touch subject.config_file
25
+ subject.send( :load_config ).should be true
26
+ subject.send( :load_config ).should be false
27
+ end
28
+
29
+ it 'should produce a string properly' do
30
+
31
+ # make sure we don't fail if a particular binary for an example doesn't exist.
32
+ subject.polls.values.each { |p| p.cmd = 'echo' }
33
+
34
+ string = subject.to_s
35
+ string.should be_a_kind_of String
36
+ string.should_not be ''
37
+ end
38
+
39
+ end
40
+
@@ -0,0 +1,51 @@
1
+
2
+ require 'dock_driver/poll'
3
+ require 'dock_driver/data_rate_poll'
4
+
5
+ include DockDriver
6
+
7
+ shared_examples 'Poll' do |klass|
8
+
9
+ it 'should be able to execute shell commands' do
10
+ p = Poll.new( :cmd => "echo" )
11
+ lambda { p.poll }.should_not raise_error
12
+ end
13
+
14
+ it 'should be able to execute blocks' do
15
+ p = Poll.new do; end
16
+ lambda { p.poll }.should_not raise_error
17
+ end
18
+
19
+ it 'should return the same object if polled quickly' do
20
+ p = Poll.new( :cmd => "echo" )
21
+ p.poll
22
+ a = p.to_s
23
+ p.poll
24
+ b = p.to_s
25
+ a.object_id.should == b.object_id
26
+ end
27
+
28
+ it 'should return a different object if polled slowly' do
29
+ p = Poll.new( :cmd => "echo", :delay => 0.1 )
30
+ p.poll
31
+ a = p.to_s
32
+ sleep 0.5
33
+ p.poll
34
+ b = p.to_s
35
+ a.object_id.should_not == b.object_id
36
+ end
37
+
38
+ end
39
+
40
+ describe Poll do
41
+
42
+ include_examples 'Poll', Poll
43
+
44
+ end
45
+
46
+ describe DataRatePoll do
47
+
48
+ include_examples 'Poll', DataRatePoll
49
+
50
+ end
51
+
@@ -0,0 +1,17 @@
1
+
2
+ require 'dock_driver'
3
+
4
+ describe DockDriver do
5
+
6
+ it 'should have a standard version number' do
7
+ defined?( VERSION ).should == 'constant'
8
+ VERSION.should =~ /^\d+\.\d+\.\d+$/
9
+ end
10
+
11
+ it 'should have a mercurial revision' do
12
+ defined?( REVISION ).should == 'constant'
13
+ REVISION.should =~ /^Revision: [[:xdigit:]]+ $/
14
+ end
15
+
16
+ end
17
+
data.tar.gz.sig ADDED
@@ -0,0 +1 @@
1
+ 3k�S���^���p���
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dock_driver
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Michael Hix
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain:
17
+ - |
18
+ -----BEGIN CERTIFICATE-----
19
+ MIIDKDCCAhCgAwIBAgIBADANBgkqhkiG9w0BAQUFADA6MQ0wCwYDVQQDDARtaWtl
20
+ MRQwEgYKCZImiZPyLGQBGRYEbXVzbDETMBEGCgmSJomT8ixkARkWA29yZzAeFw0x
21
+ MjA0MjUxODM4MjdaFw0xMzA0MjUxODM4MjdaMDoxDTALBgNVBAMMBG1pa2UxFDAS
22
+ BgoJkiaJk/IsZAEZFgRtdXNsMRMwEQYKCZImiZPyLGQBGRYDb3JnMIIBIjANBgkq
23
+ hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyYKo5tTirdfMTksMM5DnnwLtGUnAPE++
24
+ pTPOenB29rVurrI2Vw8ndjbiWtaBOwb6jVdMzEwxBwVBa4r4FdSQO8rzEm1jV/+B
25
+ LEbl5xvOy/PRAXKvaUrQYCvuYtJA1py1mGIC8evNiH4jxZl0Fn9GrjNzzuRoSi/O
26
+ nLA4dcI5InCWAtUTUtMkMPn9mz9eZRnqd2yxziciwHzHkXBqVDACeAvo4PZUtTEL
27
+ aAs/yP3Hc/AH7StrwXb2KUJexSJximkAGg1J0iMCuKTBE9e534OXnE0NgCuyOrle
28
+ lpPTxF5umMpkiTwHLrmBWez3/JyAt1wt+5YWXamQBO1bGqzG/aGU1QIDAQABozkw
29
+ NzAdBgNVHQ4EFgQUPdX0JADsZMOtODSP0KlgqTgMG1cwCQYDVR0TBAIwADALBgNV
30
+ HQ8EBAMCBLAwDQYJKoZIhvcNAQEFBQADggEBADnlpP5hNPaM2x1q/lumvpHi1NU5
31
+ n1TJ13ZdVbRT1e9HbCs2nQ6TahIdf/1vdVlVldeNRDWxe2yXSG8RrpFZV1ATu+L/
32
+ mCGPM2NBUh3zT52kMiVJFh4jqI6SWLU/6vojxZms8jpghT7giA5KNQYN6ZK3jrTK
33
+ yocRBh/rTKHm7C207qTf/iLZj4kG60ozVdkYkZPlrP6/DkfyamnTHrmtN0W30xWC
34
+ V9AGPfVm7XVfb/wPkWPD3jgA77/j4KJrIH0ML0W9qypcYgH11X3RS0hBM+cx1WcX
35
+ Edc7ShBTME9+u6K/HFwVxTOH8WJVxkwGTmxKgCevr5mZzbINH/C6LbkmfEA=
36
+ -----END CERTIFICATE-----
37
+
38
+ date: 2012-05-16 00:00:00 Z
39
+ dependencies:
40
+ - !ruby/object:Gem::Dependency
41
+ name: hoe-mercurial
42
+ prerelease: false
43
+ requirement: &id001 !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ hash: 7
49
+ segments:
50
+ - 1
51
+ - 4
52
+ - 0
53
+ version: 1.4.0
54
+ type: :development
55
+ version_requirements: *id001
56
+ - !ruby/object:Gem::Dependency
57
+ name: rdoc
58
+ prerelease: false
59
+ requirement: &id002 !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ~>
63
+ - !ruby/object:Gem::Version
64
+ hash: 19
65
+ segments:
66
+ - 3
67
+ - 10
68
+ version: "3.10"
69
+ type: :development
70
+ version_requirements: *id002
71
+ - !ruby/object:Gem::Dependency
72
+ name: hoe
73
+ prerelease: false
74
+ requirement: &id003 !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ~>
78
+ - !ruby/object:Gem::Version
79
+ hash: 7
80
+ segments:
81
+ - 3
82
+ - 0
83
+ version: "3.0"
84
+ type: :development
85
+ version_requirements: *id003
86
+ description: |-
87
+ Provides a simple executable to drive a dzen2 (or similar) dock with a
88
+ single YAML config file.
89
+
90
+ Read +example.dock_driver.yml+ for more information about how to get
91
+ started. It's located in this gem's data directory, which is usually:
92
+ $GEM_HOME/gems/dock_driver-x.y.z/data/
93
+ email:
94
+ - mike@musl.org
95
+ executables:
96
+ - dock_driver
97
+ extensions: []
98
+
99
+ extra_rdoc_files:
100
+ - History.txt
101
+ - Ideas.txt
102
+ - Manifest.txt
103
+ - README.txt
104
+ files:
105
+ - .autotest
106
+ - .hgignore
107
+ - History.txt
108
+ - Ideas.txt
109
+ - Manifest.txt
110
+ - README.txt
111
+ - Rakefile
112
+ - bin/dock_driver
113
+ - data/example.dock_driver.yml
114
+ - lib/dock_driver.rb
115
+ - lib/dock_driver/laika_hashutils.rb
116
+ - lib/dock_driver/poll.rb
117
+ - lib/dock_driver/data_rate_poll.rb
118
+ - lib/dock_driver/dock.rb
119
+ - spec/dock_driver/dock_spec.rb
120
+ - spec/dock_driver/poll_spec.rb
121
+ - spec/dock_driver_spec.rb
122
+ - .gemtest
123
+ homepage: http://hg.musl.org/projects/dock_driver/
124
+ licenses: []
125
+
126
+ post_install_message:
127
+ rdoc_options:
128
+ - --main
129
+ - README.txt
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ none: false
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ hash: 57
138
+ segments:
139
+ - 1
140
+ - 8
141
+ - 7
142
+ version: 1.8.7
143
+ required_rubygems_version: !ruby/object:Gem::Requirement
144
+ none: false
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ hash: 31
149
+ segments:
150
+ - 1
151
+ - 8
152
+ version: "1.8"
153
+ requirements: []
154
+
155
+ rubyforge_project: dock_driver
156
+ rubygems_version: 1.8.17
157
+ signing_key:
158
+ specification_version: 3
159
+ summary: Provides a simple executable to drive a dzen2 (or similar) dock with a single YAML config file
160
+ test_files: []
161
+
metadata.gz.sig ADDED
Binary file