arbi 1.0.7 → 1.0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,60 @@
1
+ #--
2
+ # Copyleft shura. [ shura1991@gmail.com ]
3
+ #
4
+ # This file is part of arbi.
5
+ #
6
+ # arbi is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # arbi is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with arbi. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ module Arbi
21
+
22
+ module Modules
23
+
24
+ module Sys
25
+
26
+ class Adapter < Arbi::Modules::Module
27
+ def initialize(data = [])
28
+ super(data)
29
+ @adapters = Dir.glob('/sys/class/power_supply/*').select {|ad|
30
+ File.read("#{ad}/type").strip == 'Mains'
31
+ }
32
+ end
33
+
34
+ def valid?
35
+ !@adapters.empty?
36
+ end
37
+
38
+ def refresh
39
+ @data = []
40
+
41
+ @adapters.each {|adapter|
42
+ @data << {
43
+ name: File.basename(adapter),
44
+ state: (File.read("#{adapter}/online").to_i.zero? ? false : true)
45
+ }
46
+ }
47
+ end
48
+
49
+ def format
50
+ tablize([['NAME', 'STATE']] + @data.map {|adapter|
51
+ [adapter[:name] || adapter['name'], (adapter[:state] || adapter['state']) ? 'on' : 'off']
52
+ })
53
+ end
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -0,0 +1,101 @@
1
+ #--
2
+ # Copyleft shura. [ shura1991@gmail.com ]
3
+ #
4
+ # This file is part of arbi.
5
+ #
6
+ # arbi is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # arbi is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with arbi. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ module Arbi
21
+
22
+ module Modules
23
+
24
+ module Sys
25
+
26
+ class Battery < Arbi::Modules::Module
27
+ def initialize(data = [])
28
+ super(data)
29
+ @batteries = Dir.glob('/sys/class/power_supply/*').select {|dir| File.read("#{dir}/type").strip == 'Battery' }
30
+ end
31
+
32
+ def valid?
33
+ !@batteries.empty?
34
+ end
35
+
36
+ def refresh
37
+ @data = []
38
+
39
+ @batteries.each {|battery|
40
+ @data << self.battery_info(battery)
41
+ }
42
+ @data << self.average(@data)
43
+ end
44
+
45
+ def format
46
+ tablize([['NAME', 'PERCENT', 'STATE', 'SANITY']] + @data.map {|x|
47
+ [x[:name] || x['name'], x[:percent] || x['percent'], x[:state] || x['state'], x[:sanity] || x['sanity']]
48
+ })
49
+ end
50
+
51
+ protected
52
+ def battery_info(dir)
53
+ raw = {
54
+ design_capacity: File.read("#{dir}/energy_full_design").strip.to_i,
55
+ last_full_capacity: File.read("#{dir}/energy_full").strip.to_i,
56
+ remaining_capacity: File.read("#{dir}/energy_now").strip.to_i,
57
+ present: (File.read("#{dir}/present").strip.to_i.zero? ? false : true),
58
+ charging_state: File.read("#{dir}/status").strip.downcase.gsub(/^full$/, 'charged')
59
+ }
60
+
61
+ return not_present(File.basename(dir)) unless raw[:present]
62
+
63
+ {
64
+ name: File.basename(dir),
65
+ sanity: ("%.1f%%" % [100.0 / raw[:design_capacity] * raw[:last_full_capacity]]),
66
+ state: raw[:charging_state],
67
+ percent: ("%.1f%%" % [100.0 / raw[:last_full_capacity] * raw[:remaining_capacity]])
68
+ }
69
+ end
70
+
71
+ def average(batteries)
72
+ avg, n = 0, 0
73
+
74
+ batteries.each {|battery|
75
+ avg += battery[:percent].gsub(/%$/, '').to_f and n += 1 if battery[:percent]
76
+ }
77
+ avg = "%.1f%%" % [avg / n] rescue false
78
+
79
+ {
80
+ name: 'AVERAGE',
81
+ sanity: false,
82
+ state: false,
83
+ percent: avg
84
+ }
85
+ end
86
+
87
+ def not_present(name)
88
+ {
89
+ name: name,
90
+ sanity: false,
91
+ state: false,
92
+ percent: false
93
+ }
94
+ end
95
+ end
96
+
97
+ end
98
+
99
+ end
100
+
101
+ end
@@ -0,0 +1,71 @@
1
+ #--
2
+ # Copyleft shura. [ shura1991@gmail.com ]
3
+ #
4
+ # This file is part of arbi.
5
+ #
6
+ # arbi is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # arbi is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with arbi. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ module Arbi
21
+
22
+ module Modules
23
+
24
+ module Sys
25
+
26
+ class Thermal < Arbi::Modules::Module
27
+ def initialize(data = [])
28
+ super(data)
29
+ @trips = {}
30
+ @tempdirs = Dir.glob('/sys/class/thermal/thermal_zone*')
31
+
32
+ @tempdirs.each {|dir|
33
+ name = File.basename(dir)
34
+
35
+ Dir.glob("#{dir}/trip_point_*").select {|x| x =~ /_temp$/ }.each {|trip|
36
+ if File.read(trip.gsub(/emp$/, 'ype')).strip == 'critical'
37
+ @trips[name] = "#{File.read(trip).to_i / 1000} C"
38
+ end
39
+ }
40
+ }
41
+ end
42
+
43
+ def valid?
44
+ !@tempdirs.empty?
45
+ end
46
+
47
+ def refresh
48
+ @data = []
49
+
50
+ @tempdirs.each {|dir|
51
+ name = File.basename(dir)
52
+ @data << {
53
+ name: name,
54
+ temperature: "#{File.read("#{dir}/temp").to_i / 1000} C",
55
+ trip_point: @trips[name]
56
+ }
57
+ }
58
+ end
59
+
60
+ def format
61
+ tablize([['NAME', 'TEMPERATURE', 'TRIP POINT']] + @data.map {|therm|
62
+ [therm[:name] || therm['name'], therm[:temperature] || therm['temperature'], therm[:trip_point] || therm['trip_point']]
63
+ })
64
+ end
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+
71
+ end
@@ -0,0 +1,42 @@
1
+ #--
2
+ # Copyleft shura. [ shura1991@gmail.com ]
3
+ #
4
+ # This file is part of arbi.
5
+ #
6
+ # arbi is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # arbi is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with arbi. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ require 'arbi/version'
21
+
22
+ module Arbi
23
+
24
+ module Modules
25
+
26
+ class Version < Module
27
+ def valid?
28
+ true
29
+ end
30
+
31
+ def refresh
32
+ @data = Arbi::VERSION
33
+ end
34
+
35
+ def format
36
+ @data
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -0,0 +1,67 @@
1
+ #--
2
+ # Copyleft shura. [ shura1991@gmail.com ]
3
+ #
4
+ # This file is part of arbi.
5
+ #
6
+ # arbi is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # arbi is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with arbi. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ require 'eventmachine'
21
+ require 'arbi/modules'
22
+
23
+ module Arbi
24
+
25
+ class Server
26
+ module Server
27
+ def post_init
28
+ send_data("OH HAI! ^_^\n")
29
+ end
30
+
31
+ def receive_data(data)
32
+ if data.strip.downcase =~ /^(quit|exit)$/
33
+ close_connection
34
+ return
35
+ end
36
+
37
+ obj = Arbi.modules[data.strip.downcase]
38
+
39
+ if obj
40
+ send_data(obj.to_json)
41
+ else
42
+ send_data(Arbi::Modules::Error.new('Command doesn\'t exist').to_json)
43
+ end
44
+ rescue Exception => e
45
+ Arbi.debug(e.to_s)
46
+ end
47
+ end
48
+
49
+ def initialize(address = '127.0.0.1', port = 6969)
50
+ @address = address || '127.0.0.1'
51
+ @port = port || 6969
52
+ end
53
+
54
+ def start
55
+ EventMachine.run {
56
+ TimeLine.run
57
+ EventMachine.start_server(@address, @port, Arbi::Server::Server)
58
+ Arbi.debug("Starting server on #{@address}:#{@port}")
59
+ }
60
+ end
61
+
62
+ def self.start(address = '127.0.0.1', port = 6969)
63
+ self.new(address, port).start
64
+ end
65
+ end
66
+
67
+ end
@@ -0,0 +1,70 @@
1
+ #--
2
+ # Copyleft shura. [ shura1991@gmail.com ]
3
+ #
4
+ # This file is part of arbi.
5
+ #
6
+ # arbi is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # arbi is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with arbi. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ require 'eventmachine'
21
+ require 'timeout'
22
+
23
+ module TimeLine
24
+ class Job
25
+ attr_reader :every, :timeout, :proc
26
+
27
+ def initialize(ev = 2, to = 5, &blk)
28
+ self.every = ev
29
+ self.timeout = to
30
+ self.proc = blk
31
+
32
+ TimeLine.register(self)
33
+ end
34
+
35
+ def every=(ev)
36
+ raise ArgumentError, "every must be an Integer > 0" unless ev.is_a?(Integer) and ev > 0
37
+ @every = ev
38
+ end
39
+
40
+ def timeout=(to)
41
+ raise ArgumentError, "timeout must be an Integer > 0" unless to.is_a?(Integer) and to > 0
42
+ @timeout = to
43
+ end
44
+
45
+ def proc=(blk)
46
+ raise ArgumentError, "proc must be a Proc" unless blk.is_a?(Proc)
47
+ @proc = blk
48
+ end
49
+ end
50
+
51
+ class << self
52
+ def register(job)
53
+ raise ArgumentError, "job must be a TimeLine::Job" unless job.is_a?(TimeLine::Job)
54
+ @@jobs ||= []
55
+ @@jobs << job
56
+ end
57
+
58
+ def run
59
+ @@jobs ||= []
60
+ @@jobs.each {|job|
61
+ EventMachine::PeriodicTimer.new(job.every) do
62
+ timeout(job.timeout) {
63
+ job.proc.call
64
+ }
65
+ end
66
+ }
67
+ self
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,81 @@
1
+ #--
2
+ # Copyleft shura. [ shura1991@gmail.com ]
3
+ #
4
+ # This file is part of arbi.
5
+ #
6
+ # arbi is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # arbi is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with arbi. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ class Numeric
21
+
22
+ module Scalar
23
+ attr_accessor :unit
24
+
25
+ MULTIPLIERS = {
26
+ ?Y => 10 ** 24, ?Z => 10 ** 21, ?E => 10 ** 18,
27
+ ?P => 10 ** 15, ?T => 10 ** 12, ?G => 10 ** 9,
28
+ ?M => 10 ** 6, ?k => 10 ** 3, ?h => 10 ** 2, 'da' => 10,
29
+
30
+ ?y => 10 ** -24, ?z => 10 ** -21, ?a => 10 ** -18,
31
+ ?f => 10 ** -15, ?p => 10 ** -12, ?n => 10 ** -9,
32
+ ?u => 10 ** -9, ?m => 10 ** -3, ?c => 10 ** -2, ?d => 10 ** -1
33
+ }
34
+
35
+ alias __method_missing__ method_missing
36
+ def method_missing(sym, *args, &blk)
37
+ if MULTIPLIERS.include?(sym.to_s)
38
+ self / MULTIPLIERS[sym.to_s]
39
+ else
40
+ self.__method_missing__(sym, *args, &blk) if sym != :to_str
41
+ end
42
+ end
43
+ end
44
+
45
+ def self.parse(str)
46
+ if str.strip.match(/^([^\s]+)\s+(#{Numeric::Scalar::MULTIPLIERS.keys.map {|x|
47
+ Regexp.escape(x)
48
+ }.join(?|)})?(.*?)$/)
49
+ num, mul, unit = $1, $2, $3
50
+ v = begin
51
+ Integer(num)
52
+ rescue ArgumentError
53
+ Float(num) rescue nil
54
+ end
55
+
56
+ return nil unless v
57
+
58
+ if Numeric::Scalar::MULTIPLIERS[mul]
59
+ v = (v * Numeric::Scalar::MULTIPLIERS[mul]).to_f
60
+ end
61
+
62
+ if !unit.empty?
63
+ v.unit = unit.dup
64
+ end
65
+
66
+ return v
67
+ end
68
+ end
69
+ end
70
+
71
+ class Integer
72
+ include Numeric::Scalar
73
+ end
74
+
75
+ class Float
76
+ include Numeric::Scalar
77
+ end
78
+
79
+ class Rational
80
+ include Numeric::Scalar
81
+ end