rmonitor 1.0.1 → 2.0.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.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +49 -40
- data/bin/rmonitor +38 -100
- data/lib/rmonitor.rb +17 -20
- data/lib/rmonitor/actions.rb +30 -0
- data/lib/rmonitor/actions/builder.rb +15 -0
- data/lib/rmonitor/actions/dsl.rb +23 -0
- data/lib/rmonitor/cache.rb +12 -0
- data/lib/rmonitor/capabilities.rb +38 -0
- data/lib/rmonitor/capabilities/builder.rb +15 -0
- data/lib/rmonitor/capabilities/dsl.rb +15 -0
- data/lib/rmonitor/commands/cl/base.rb +13 -0
- data/lib/rmonitor/commands/cl/invoke.rb +22 -0
- data/lib/rmonitor/commands/cl/list.rb +43 -0
- data/lib/rmonitor/commands/cl/update.rb +20 -0
- data/lib/rmonitor/commands/invoke.rb +23 -0
- data/lib/rmonitor/commands/list.rb +13 -0
- data/lib/rmonitor/commands/update.rb +18 -0
- data/lib/rmonitor/config.rb +27 -0
- data/lib/rmonitor/config/builder.rb +21 -0
- data/lib/rmonitor/config/dsl.rb +25 -0
- data/lib/rmonitor/invoker.rb +9 -0
- data/lib/rmonitor/matcher.rb +32 -0
- data/lib/rmonitor/profile/builder.rb +15 -0
- data/lib/rmonitor/profile/dsl.rb +15 -0
- data/lib/rmonitor/selector.rb +14 -0
- data/lib/rmonitor/strategies/base.rb +10 -0
- data/lib/rmonitor/strategies/optimistic.rb +15 -0
- data/lib/rmonitor/strategies/pessimistic.rb +17 -0
- data/lib/rmonitor/transformer.rb +38 -0
- data/lib/rmonitor/version.rb +1 -1
- data/lib/rmonitor/xrandr.rb +16 -0
- data/test/actions/builder_test.rb +27 -0
- data/test/actions_test.rb +60 -0
- data/test/cache_test.rb +30 -0
- data/test/capabilities/builder_test.rb +23 -0
- data/test/capabilities_test.rb +114 -0
- data/test/commands/cl/invoke_test.rb +38 -0
- data/test/commands/cl/list_test.rb +36 -0
- data/test/commands/cl/update_test.rb +24 -0
- data/test/commands/invoke_test.rb +86 -0
- data/test/commands/list_test.rb +50 -0
- data/test/commands/update_test.rb +67 -0
- data/test/config/builder_test.rb +51 -0
- data/test/config_test.rb +68 -0
- data/test/matcher_test.rb +90 -0
- data/test/profile/builder_test.rb +26 -0
- data/test/selector_test.rb +30 -0
- data/test/strategies/optimistic_test.rb +24 -0
- data/test/strategies/pessimistic_test.rb +26 -0
- data/test/test_helper.rb +19 -0
- data/test/transformer_test.rb +159 -0
- data/test/xrandr_test.rb +76 -0
- metadata +178 -28
- data/.rspec +0 -1
- data/Gemfile +0 -3
- data/Gemfile.lock +0 -24
- data/lib/rmonitor/devices.rb +0 -29
- data/lib/rmonitor/helpers/dsl_helpers.rb +0 -38
- data/lib/rmonitor/helpers/profile_helpers.rb +0 -48
- data/lib/rmonitor/helpers/xrandr_read_helpers.rb +0 -75
- data/lib/rmonitor/helpers/xrandr_write_helpers.rb +0 -55
- data/lib/rmonitor/profiles.rb +0 -51
- data/rmonitor.gemspec +0 -44
- data/spec/lib/helpers/dsl_helper_spec.rb +0 -29
- data/spec/lib/helpers/profile_helpers_spec.rb +0 -138
- data/spec/lib/helpers/xrandr_read_helpers_spec.rb +0 -259
- data/spec/lib/helpers/xrandr_write_helpers_spec.rb +0 -158
- data/spec/support/device_helper.rb +0 -3
- data/spec/support/profile_helper.rb +0 -3
- data/spec/support/string_helpers.rb +0 -25
@@ -0,0 +1,15 @@
|
|
1
|
+
require "rmonitor/capabilities/dsl"
|
2
|
+
|
3
|
+
class RMonitor
|
4
|
+
class Capabilities
|
5
|
+
class Builder
|
6
|
+
class << self
|
7
|
+
def define(&block)
|
8
|
+
dsl = RMonitor::Capabilities::DSL.new
|
9
|
+
dsl.instance_eval(&block)
|
10
|
+
dsl.capabilities
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "rmonitor/commands/invoke"
|
2
|
+
|
3
|
+
class RMonitor
|
4
|
+
module Commands
|
5
|
+
module CL
|
6
|
+
class Invoke
|
7
|
+
def initialize(options = {})
|
8
|
+
@err = options[:err] || $stderr
|
9
|
+
@invoke = options[:invoke] || RMonitor::Commands::Invoke.new(options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute(name)
|
13
|
+
@invoke.execute(name)
|
14
|
+
rescue RMonitor::UnknownProfileError
|
15
|
+
@err.puts "unknown profile"
|
16
|
+
rescue RMonitor::UninvokableProfileError
|
17
|
+
@err.puts "profile is not invokable"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "rmonitor/commands/list"
|
2
|
+
|
3
|
+
class RMonitor
|
4
|
+
module Commands
|
5
|
+
module CL
|
6
|
+
class List
|
7
|
+
def initialize(options = {})
|
8
|
+
@out = options[:out] || $stdout
|
9
|
+
@list = options[:list] || RMonitor::Commands::List.new(options)
|
10
|
+
@matcher = options[:matcher] || RMonitor::Matcher.new(options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute
|
14
|
+
profiles = @list.execute
|
15
|
+
|
16
|
+
profiles.each do |profile|
|
17
|
+
@out.write("#{profile[:name]}\t")
|
18
|
+
|
19
|
+
if @matcher.invokable?(profile)
|
20
|
+
@out.write("invokable")
|
21
|
+
else
|
22
|
+
@out.write("uninvokable")
|
23
|
+
end
|
24
|
+
|
25
|
+
profile[:devices].each do |device|
|
26
|
+
@out.write("\t#{device[:name]}")
|
27
|
+
|
28
|
+
if device[:mode] && device[:rate]
|
29
|
+
@out.write(" (#{device[:mode]} #{device[:rate]})")
|
30
|
+
elsif device[:mode]
|
31
|
+
@out.write(" (#{device[:mode]})")
|
32
|
+
elsif device[:rate]
|
33
|
+
@out.write(" (#{device[:rate]})")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
@out.write("\n")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "rmonitor/commands/update"
|
2
|
+
|
3
|
+
class RMonitor
|
4
|
+
module Commands
|
5
|
+
module CL
|
6
|
+
class Update
|
7
|
+
def initialize(options = {})
|
8
|
+
@err = options[:err] || $stderr
|
9
|
+
@update = options[:update] || RMonitor::Commands::Update.new(options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute
|
13
|
+
@update.execute
|
14
|
+
rescue RMonitor::NoInvokableProfileError
|
15
|
+
@err.puts "no invokable profile"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class RMonitor
|
2
|
+
module Commands
|
3
|
+
class Invoke
|
4
|
+
def initialize(options = {})
|
5
|
+
@profiles = options[:profiles] || Config.new.profiles
|
6
|
+
@matcher = options[:matcher] || Matcher.new(options)
|
7
|
+
@strategy = options[:strategy] || Strategies::Pessimistic.new(options)
|
8
|
+
@factory = options[:factory] || Actions.new(options)
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute(name)
|
12
|
+
profile = @profiles.find { |p| p[:name] == name }
|
13
|
+
|
14
|
+
raise UnknownProfileError unless profile
|
15
|
+
raise UninvokableProfileError unless @matcher.invokable?(profile)
|
16
|
+
|
17
|
+
actions = @factory.create(profile)
|
18
|
+
|
19
|
+
@strategy.execute(actions)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class RMonitor
|
2
|
+
module Commands
|
3
|
+
class Update
|
4
|
+
def initialize(options = {})
|
5
|
+
@invoke = options[:invoke] || Invoke.new(options)
|
6
|
+
@selector = options[:selector] || Selector.new(options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def execute
|
10
|
+
profile = @selector.first_invokable
|
11
|
+
|
12
|
+
raise NoInvokableProfileError unless profile
|
13
|
+
|
14
|
+
@invoke.execute(profile[:name])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "rmonitor/config/builder"
|
2
|
+
|
3
|
+
class RMonitor
|
4
|
+
class Config
|
5
|
+
def profiles
|
6
|
+
Builder.define read
|
7
|
+
end
|
8
|
+
|
9
|
+
def read
|
10
|
+
File.read self.class.config_path
|
11
|
+
end
|
12
|
+
|
13
|
+
class << self
|
14
|
+
attr_writer :config_path
|
15
|
+
|
16
|
+
def config_path
|
17
|
+
@config_path || default_config_path
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def default_config_path
|
23
|
+
File.join(Dir.home, ".config", "rmonitor", "config.rb")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "rmonitor/config/dsl"
|
2
|
+
|
3
|
+
class RMonitor
|
4
|
+
class Config
|
5
|
+
class Builder
|
6
|
+
class << self
|
7
|
+
def define(input = nil, &block)
|
8
|
+
dsl = RMonitor::Config::DSL.new
|
9
|
+
|
10
|
+
if input
|
11
|
+
dsl.instance_eval(input)
|
12
|
+
else
|
13
|
+
dsl.instance_eval(&block)
|
14
|
+
end
|
15
|
+
|
16
|
+
dsl.profiles
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "rmonitor/profile/builder"
|
2
|
+
|
3
|
+
class RMonitor
|
4
|
+
class Config
|
5
|
+
class DSL
|
6
|
+
attr_accessor :profiles
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@profiles = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def profile(name, options = {}, &block)
|
13
|
+
@profiles << RMonitor::Profile::Builder.define(name, options, &block)
|
14
|
+
|
15
|
+
if @profiles.last.has_key?(:only_if)
|
16
|
+
@profiles.last[:only_if] = method(@profiles.last[:only_if])
|
17
|
+
end
|
18
|
+
|
19
|
+
if @profiles.last.has_key?(:not_if)
|
20
|
+
@profiles.last[:not_if] = method(@profiles.last[:not_if])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class RMonitor
|
2
|
+
class Matcher
|
3
|
+
def initialize(options = {})
|
4
|
+
@capabilities = options[:capabilities] || Capabilities.new(options).parse
|
5
|
+
end
|
6
|
+
|
7
|
+
def invokable?(profile)
|
8
|
+
return false if profile.has_key?(:only_if) && !profile[:only_if].call
|
9
|
+
return false if profile.has_key?(:not_if) && profile[:not_if].call
|
10
|
+
|
11
|
+
profile[:devices].all? do |device|
|
12
|
+
has_desired_capability? device
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def has_desired_capability?(desire)
|
19
|
+
@capabilities.any? do |capability|
|
20
|
+
match_desire_capability?(desire, capability)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def match_desire_capability?(desire, capability)
|
25
|
+
return false if desire[:name] != capability[:name]
|
26
|
+
return false if desire[:mode] && desire[:mode] != capability[:mode]
|
27
|
+
return false if desire[:rate] && desire[:rate] != capability[:rate]
|
28
|
+
|
29
|
+
true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "rmonitor/profile/dsl"
|
2
|
+
|
3
|
+
class RMonitor
|
4
|
+
module Profile
|
5
|
+
class Builder
|
6
|
+
class << self
|
7
|
+
def define(name, options = {}, &block)
|
8
|
+
dsl = RMonitor::Profile::DSL.new
|
9
|
+
dsl.instance_eval &block
|
10
|
+
options.merge :name => name, :devices => dsl.devices
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class RMonitor
|
2
|
+
class Selector
|
3
|
+
def initialize(options = {})
|
4
|
+
@profiles = options[:profiles] || Config.new.profiles
|
5
|
+
@matcher = options[:matcher] || Matcher.new(options)
|
6
|
+
end
|
7
|
+
|
8
|
+
def first_invokable
|
9
|
+
@profiles.find do |profile|
|
10
|
+
@matcher.invokable? profile
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "rmonitor/strategies/base"
|
2
|
+
|
3
|
+
class RMonitor
|
4
|
+
module Strategies
|
5
|
+
class Optimistic < Base
|
6
|
+
def execute(actions)
|
7
|
+
transformations = actions.map do |action|
|
8
|
+
@transformer.transform(action)
|
9
|
+
end
|
10
|
+
|
11
|
+
@xrandr.invoke(*transformations.flatten)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "rmonitor/strategies/base"
|
2
|
+
|
3
|
+
class RMonitor
|
4
|
+
module Strategies
|
5
|
+
class Pessimistic < Base
|
6
|
+
def execute(actions)
|
7
|
+
transformations = actions.map do |action|
|
8
|
+
@transformer.transform(action)
|
9
|
+
end
|
10
|
+
|
11
|
+
transformations.each do |transformation|
|
12
|
+
@xrandr.invoke(*transformation)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class RMonitor
|
2
|
+
class Transformer
|
3
|
+
def transform(action)
|
4
|
+
case action.delete(:action)
|
5
|
+
when :off
|
6
|
+
transform_off(action)
|
7
|
+
when :on
|
8
|
+
transform_on(action)
|
9
|
+
when :option
|
10
|
+
transforn_option(action)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def transform_on(action)
|
17
|
+
args = ["--output", action.delete(:name)]
|
18
|
+
|
19
|
+
action.each do |key, value|
|
20
|
+
args << "--#{key.to_s.gsub("_", "-")}"
|
21
|
+
|
22
|
+
unless value.is_a?(TrueClass)
|
23
|
+
args << value.to_s
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
args
|
28
|
+
end
|
29
|
+
|
30
|
+
def transform_off(action)
|
31
|
+
["--output", action.delete(:name), "--off"]
|
32
|
+
end
|
33
|
+
|
34
|
+
def transforn_option(action)
|
35
|
+
["--#{action[:name].to_s.gsub("_", "-")}", action[:value].to_s]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|