linux_stat 0.9.0 → 1.0.3

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.
@@ -62,7 +62,7 @@ module LinuxStat
62
62
  end
63
63
 
64
64
  ##
65
- # mount_point(dev = root)
65
+ # = mount_point(dev = root)
66
66
  #
67
67
  # Where device = block device.
68
68
  #
@@ -94,7 +94,7 @@ module LinuxStat
94
94
  end
95
95
 
96
96
  ##
97
- # list_devices_mount_point()
97
+ # = list_devices_mount_point()
98
98
  #
99
99
  # It shows all the block devices corresponding to mount points.
100
100
  #
@@ -120,7 +120,7 @@ module LinuxStat
120
120
  end
121
121
 
122
122
  ##
123
- # devices_stat
123
+ # = devices_stat
124
124
  #
125
125
  # [ Not to confuse this method with device_stat(dev) which shows only one device's info ]
126
126
  #
@@ -162,7 +162,7 @@ module LinuxStat
162
162
  end
163
163
 
164
164
  ##
165
- # device_stat(dev = root)
165
+ # = device_stat(dev = root)
166
166
  #
167
167
  # [ Not to confuse this method with devices_stat() which shows all devices ]
168
168
  #
@@ -17,7 +17,9 @@ module LinuxStat
17
17
  # Returns the total bytes received and transmitted as Hash.
18
18
  #
19
19
  # For example:
20
- # {:received=>56602867, :transmitted=>6940922}
20
+ # LinuxStat::Net.usage
21
+ #
22
+ # => {:received=>56602867, :transmitted=>6940922}
21
23
  #
22
24
  # But if the status isn't available it will return an empty Hash.
23
25
  def total_bytes
@@ -68,7 +70,9 @@ module LinuxStat
68
70
  # The return type is a Hash, containg the current internet usage (received, transmit) in B/s.
69
71
  #
70
72
  # For example:
71
- # {:received=>436060.0, :transmitted=>50350.0}
73
+ # LinuxStat::Net.usage
74
+ #
75
+ # => {:received=>436060.0, :transmitted=>50350.0}
72
76
  #
73
77
  # If the system transmits 100 kb in the interval,
74
78
  #
@@ -3,7 +3,9 @@ module LinuxStat
3
3
  class << self
4
4
  ##
5
5
  # Reads /etc/os-release and returns a Hash. For example:
6
- # {:NAME=>"Arch Linux", :PRETTY_NAME=>"Arch Linux", :ID=>"arch", :BUILD_ID=>"rolling", :ANSI_COLOR=>"38;2;23;147;209", :HOME_URL=>"https://www.archlinux.org/", :DOCUMENTATION_URL=>"https://wiki.archlinux.org/", :SUPPORT_URL=>"https://bbs.archlinux.org/", :BUG_REPORT_URL=>"https://bugs.archlinux.org/", :LOGO=>"archlinux"}
6
+ # LinuxStat::OS.os_release
7
+ #
8
+ # => {:NAME=>"Arch Linux", :PRETTY_NAME=>"Arch Linux", :ID=>"arch", :BUILD_ID=>"rolling", :ANSI_COLOR=>"38;2;23;147;209", :HOME_URL=>"https://www.archlinux.org/", :DOCUMENTATION_URL=>"https://wiki.archlinux.org/", :SUPPORT_URL=>"https://bbs.archlinux.org/", :BUG_REPORT_URL=>"https://bugs.archlinux.org/", :LOGO=>"archlinux"}
7
9
  #
8
10
  # If the info isn't available, it will return an empty Hash.
9
11
  #
@@ -13,13 +15,14 @@ module LinuxStat
13
15
  # Because changing the /etc/lsb-release
14
16
  # isn't expected in runtime.
15
17
  def os_release
16
- # cached (memoized) ; as changing the value in runtime is unexpected
17
18
  @@os_release ||= File.readable?('/etc/os-release') ? release('/etc/os-release') : {}
18
19
  end
19
20
 
20
21
  ##
21
22
  # Reads /etc/lsb-release and returns a Hash. For example:
22
- # {:LSB_VERSION=>"1.4", :DISTRIB_ID=>"Arch", :DISTRIB_RELEASE=>"rolling", :DISTRIB_DESCRIPTION=>"Arch Linux"}
23
+ # LinuxStat::OS.lsb_release
24
+ #
25
+ # => {:LSB_VERSION=>"1.4", :DISTRIB_ID=>"Arch", :DISTRIB_RELEASE=>"rolling", :DISTRIB_DESCRIPTION=>"Arch Linux"}
23
26
  #
24
27
  # If the info isn't available, it will return an empty Hash.
25
28
  #
@@ -28,7 +31,6 @@ module LinuxStat
28
31
  # The information is also cached, and once loaded, won't change in runtime.
29
32
  # Because changing the /etc/lsb-release isn't expected in runtime.
30
33
  def lsb_release
31
- # cached (memoized) ; as changing the value in runtime is unexpected
32
34
  @@lsb_release ||= File.readable?('/etc/lsb-release') ? release('/etc/lsb-release') : {}
33
35
  end
34
36
 
@@ -104,7 +106,9 @@ module LinuxStat
104
106
 
105
107
  ##
106
108
  # Reads /proc/uptime and returns the system uptime:
107
- # {:hour=>10, :minute=>34, :second=>12.59}
109
+ # LinuxStat::OS.uptime
110
+ #
111
+ # => {:hour=>10, :minute=>34, :second=>12.59}
108
112
  #
109
113
  # If the stat isn't available, an empty hash is returned.
110
114
  def uptime
@@ -645,7 +645,8 @@ module LinuxStat
645
645
 
646
646
  private
647
647
  def get_ticks
648
- @@ticks ||= Sysconf.sc_clk_tck
648
+ @@sc_clk_tck ||= LinuxStat::Sysconf.sc_clk_tck
649
+ @@ticks ||= @@sc_clk_tck < 1 ? 100 : @@sc_clk_tck
649
650
  end
650
651
 
651
652
  # Just to avoid multiple calculations!...
@@ -656,7 +657,7 @@ module LinuxStat
656
657
  end
657
658
 
658
659
  def pagesize
659
- @@pagesize ||= LinuxStat::Sysconf.pagesize
660
+ @@pagesize ||= LinuxStat::Sysconf.pagesize.to_i
660
661
  end
661
662
 
662
663
  def cpu_count
@@ -0,0 +1,194 @@
1
+ module LinuxStat
2
+ module USB
3
+ class << self
4
+ ##
5
+ # = devices_stat(hwdata: true)
6
+ #
7
+ # Returns details about the devices found in /sys/bus/usb/devices/
8
+ #
9
+ # The return value is an Array of multiple Hashes. If there's no info available,
10
+ # it will rather return an empty Array.
11
+ #
12
+ # On Android Termux for example, it can not list the directories because they are
13
+ # not readable the the regular user.
14
+ #
15
+ # It can have information like:
16
+ #
17
+ # id, vendor id, product id, manufacturer, serial, bus number, dev number,
18
+ # b_max_power, b_max_packet_size, etc.
19
+ #
20
+ # An example of the returned sample from a test machine is:
21
+ # LinuxStat::USB.devices_stat
22
+ #
23
+ # [{:path=>"/sys/bus/usb/devices/1-1.2/", :id=>"04d9:1203", :vendor_id=>"04d9", :product_id=>"1203", :bus_num=>1, :dev_num=>4, :hwdata=>{:vendor=>"Holtek Semiconductor, Inc.", :product=>"Keyboard"}, :authorized=>true, :b_max_power=>"100mA", :b_max_packet_size0=>8}
24
+ #
25
+ # Right, it's an array of Hashes.
26
+ #
27
+ # It also takes one option. The hwdata, which is true by default.
28
+ #
29
+ # Information about usb devices is found inside /usr/share/hwdata/usb.ids
30
+ #
31
+ # The data contains the vendor and the product.
32
+ #
33
+ # If the option is enabled, it will try look at /usr/share/hwdata/usb.ids
34
+ #
35
+ # But the file will be read only once. The consecutive calls to this method
36
+ # won't open the hwdata all the times.
37
+ #
38
+ # But if there's no hwdata, the Hash returned by this method will not contain
39
+ # hwdata key.
40
+ #
41
+ # The data is only populated if it's available. For example, if there's no
42
+ # manufacturer available for the product, the returned Hash will not contain the
43
+ # information about the manufacturer.
44
+ #
45
+ # Also note that if there's no info available or no USB devices, it will return an empty
46
+ # Hash.
47
+ def devices_stat(hwdata: true)
48
+ @@sys_usb_readable ||= File.readable?('/sys/bus/usb/devices/')
49
+ return [] unless @@sys_usb_readable
50
+
51
+ Dir['/sys/bus/usb/devices/*/'.freeze].sort!.map! { |x|
52
+ id_vendor_file = File.join(x, 'idVendor'.freeze)
53
+ next unless File.readable?(id_vendor_file)
54
+ id_vendor = IO.read(id_vendor_file).strip
55
+
56
+ id_product_file = File.join(x, 'idProduct'.freeze)
57
+ next unless File.readable?(id_vendor_file)
58
+ id_product = IO.read(id_product_file).strip
59
+
60
+ bus_num_file = File.join(x, 'busnum'.freeze)
61
+ bus_num = File.readable?(bus_num_file) ? IO.read(bus_num_file).strip : ''.freeze
62
+
63
+ dev_num_file = File.join(x, 'devnum'.freeze)
64
+ dev_num = File.readable?(dev_num_file) ? IO.read(dev_num_file).strip : ''.freeze
65
+
66
+ serial_file = File.join(x, 'serial'.freeze)
67
+ serial = File.readable?(serial_file) ? IO.read(serial_file).strip : ''.freeze
68
+
69
+ product_file = File.join(x, 'product'.freeze)
70
+ product = File.readable?(product_file) ? IO.read(product_file).strip : ''.freeze
71
+
72
+ manufacturer_file = File.join(x, 'manufacturer'.freeze)
73
+ manufacturer = File.readable?(manufacturer_file) ? IO.read(manufacturer_file).strip : ''.freeze
74
+
75
+ removable_file = File.join(x, 'removable'.freeze)
76
+ removable = File.readable?(removable_file) ? IO.read(removable_file).strip : ''.freeze
77
+
78
+ authorized_file = File.join(x, 'authorized'.freeze)
79
+ authorized = File.readable?(authorized_file) ? IO.read(authorized_file).to_i : ''.freeze
80
+
81
+ b_max_power_file = File.join(x, 'bMaxPower'.freeze)
82
+ b_max_power = File.readable?(b_max_power_file) ? IO.read(b_max_power_file).strip : ''.freeze
83
+
84
+ b_max_packet_size0_file = File.join(x, 'bMaxPacketSize0'.freeze)
85
+ b_max_packet_size0 = File.readable?(b_max_packet_size0_file) ? IO.read(b_max_packet_size0_file).to_i : ''.freeze
86
+
87
+ query = hwdata ? query_hwdata(id_vendor, id_product) : {}
88
+
89
+ removable.downcase!
90
+ is_removable = if removable == 'removable'.freeze
91
+ true
92
+ elsif removable == 'unknown'.freeze
93
+ nil
94
+ else
95
+ false
96
+ end
97
+
98
+ ret = {
99
+ path: x, id: "#{id_vendor}:#{id_product}",
100
+ vendor_id: id_vendor, product_id: id_product
101
+ }
102
+
103
+ ret.merge!(bus_num: bus_num.to_i) unless bus_num.empty?
104
+ ret.merge!(dev_num: dev_num.to_i) unless dev_num.empty?
105
+
106
+ ret.merge!(serial: serial) unless serial.empty?
107
+
108
+ ret.merge!(hwdata: query) unless query.empty?
109
+ ret.merge!(product: product) unless product.empty?
110
+ ret.merge!(manufacturer: manufacturer) unless manufacturer.empty?
111
+
112
+ ret.merge!(removable: is_removable) unless is_removable.nil?
113
+ ret.merge!(authorized: authorized == 1)
114
+
115
+ ret.merge!(b_max_power: b_max_power) unless b_max_power.empty?
116
+ ret.merge!(b_max_packet_size0: b_max_packet_size0) if b_max_packet_size0
117
+ }.tap(&:compact!)
118
+ end
119
+
120
+ ##
121
+ # Opens /sys/bus/usb/devices, and counts the total number of
122
+ # devices connected to the USB interface.
123
+ # The return type is an integer.
124
+ #
125
+ # It checks for devices with vendor and product id file.
126
+ # If there's no such file, it will not count them as a USB device.
127
+ #
128
+ # It could be also an integrated hub or a webcam, as well as
129
+ # external hotpluggable devices like printer, USB storage devices,
130
+ # USB mouse, USB keyboard, USB joypad etc.
131
+ #
132
+ # But if the information isn't available, it will return nil.
133
+ def count
134
+ @@sys_usb_readable ||= File.readable?('/sys/bus/usb/devices/')
135
+ return nil unless @@sys_usb_readable
136
+
137
+ Dir['/sys/bus/usb/devices/*/'.freeze].count { |x|
138
+ id_vendor_file = File.join(x, 'idVendor'.freeze)
139
+ id_product_file = File.join(x, 'idProduct'.freeze)
140
+ File.readable?(id_vendor_file) && File.readable?(id_product_file)
141
+ }
142
+ end
143
+
144
+ alias count_devices count
145
+
146
+ private
147
+ def hwdata
148
+ @@hwdata_file ||= "/usr/share/hwdata/usb.ids"
149
+
150
+ @@hwdata ||= if File.readable?(@@hwdata_file)
151
+ file_data = IO.readlines(@@hwdata_file, encoding: 'ASCII-8BIT')
152
+ ret, vendor_id = {}, nil
153
+
154
+ i = -1
155
+ file_data_size = file_data.size
156
+
157
+ while (i += 1) < file_data_size
158
+ x = file_data[i]
159
+
160
+ _lstripped = x.lstrip
161
+ next if _lstripped[0] == ?#.freeze || _lstripped.empty?
162
+
163
+ if x[0] == ?\t.freeze
164
+ next unless vendor_id
165
+
166
+ data = x.tap(&:strip!)
167
+ device_id = data[/\A.*?\s/].to_s.strip
168
+ device = data[device_id.length..-1].to_s.strip
169
+ ret[vendor_id][1][device_id] = device
170
+ else
171
+ data = x
172
+ vendor_id = data[/\A.*?\s/].to_s.strip
173
+ vendor = data[vendor_id.length..-1].to_s.strip
174
+ ret[vendor_id] = [vendor, {}]
175
+ end
176
+ end
177
+
178
+ ret
179
+ else
180
+ {}
181
+ end
182
+ end
183
+
184
+ def query_hwdata(vendor_id, product_id)
185
+ vendor = hwdata[vendor_id]
186
+ if vendor
187
+ {vendor: vendor[0], product: vendor[1][product_id]}
188
+ else
189
+ {}
190
+ end
191
+ end
192
+ end
193
+ end
194
+ end
@@ -1,3 +1,3 @@
1
1
  module LinuxStat
2
- VERSION ||= "0.9.0"
2
+ VERSION ||= "1.0.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: linux_stat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sourav Goswami
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-21 00:00:00.000000000 Z
11
+ date: 2020-12-25 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Linux only, efficient linux system utilization reporting and system monitoring
14
14
  gem
@@ -18,9 +18,9 @@ executables:
18
18
  - linuxstat.rb
19
19
  extensions:
20
20
  - ext/fs_stat/extconf.rb
21
+ - ext/nproc/extconf.rb
21
22
  - ext/sysconf/extconf.rb
22
23
  - ext/utsname/extconf.rb
23
- - ext/nproc/extconf.rb
24
24
  extra_rdoc_files:
25
25
  - README.md
26
26
  files:
@@ -51,6 +51,7 @@ files:
51
51
  - lib/linux_stat/process.rb
52
52
  - lib/linux_stat/process_info.rb
53
53
  - lib/linux_stat/swap.rb
54
+ - lib/linux_stat/usb.rb
54
55
  - lib/linux_stat/user.rb
55
56
  - lib/linux_stat/version.rb
56
57
  homepage: https://github.com/Souravgoswami/linux_stat/