arbi 1.0.7 → 1.0.8

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,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