dock_driver 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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