File Coverage

blib/lib/App/Sys/Info.pm
Criterion Covered Total %
statement 197 242 81.4
branch 33 86 38.3
condition 12 36 33.3
subroutine 36 38 94.7
pod 3 3 100.0
total 281 405 69.3


line stmt bran cond sub pod time code
1             package App::Sys::Info;
2 1     1   62574 use strict;
  1         3  
  1         94  
3 1     1   8 use warnings;
  1         2  
  1         84  
4              
5             our $VERSION = '0.23';
6              
7 1     1   6 use constant CP_UTF8 => 65_001;
  1         8  
  1         113  
8 1     1   6 use constant LAST_ELEMENT => -1;
  1         2  
  1         58  
9              
10 1     1   6 use Carp qw( croak );
  1         3  
  1         3748  
11 1     1   5059 use Format::Human::Bytes;
  1         2054  
  1         39  
12 1     1   1174 use POSIX qw( locale_h );
  1         37956  
  1         10  
13 1     1   16634 use Text::Table qw();
  1         58739  
  1         36  
14 1     1   3407 use Time::Elapsed qw( elapsed );
  1         7399  
  1         8  
15 1     1   1215 use Sys::Info qw();
  1         29235  
  1         30  
16 1     1   11 use Sys::Info::Constants qw( NEW_PERL OSID );
  1         2  
  1         84  
17              
18             my($NEED_CHCP, $OLDCP);
19              
20             BEGIN {
21 1     1   6 no strict qw( refs );
  1         3  
  1         68  
22 1     1   4 foreach my $id ( qw( info os cpu fhb meta NA ) ) {
23 6     25   17 *{ $id } = sub () { return shift->{$id} };
  6         3131  
  25         155  
24             }
25             }
26              
27             END {
28 1 50 33 1   568 _chcp( $OLDCP ) if $NEED_CHCP && $OLDCP;
29             }
30              
31             sub _chcp {
32 0   0 0   0 my $enc = shift || croak 'No encoding specified';
33 0         0 system chcp => $enc, '2>nul', '1>nul';
34 0         0 return;
35             }
36              
37             sub new {
38 1     1 1 4 my $class = shift;
39 1         13 my $i = Sys::Info->new;
40 1         40 my $self = {
41             LOCALE => setlocale( LC_CTYPE ),
42             NA => 'N/A',
43             info => $i,
44             os => $i->os,
45             cpu => $i->device('CPU'),
46             fhb => Format::Human::Bytes->new,
47             };
48 1         30006 $self->{meta} = { $self->{os}->meta };
49 1         57230 bless $self, $class;
50 1         6 return $self;
51             }
52              
53             sub run {
54 1     1 1 17 my $self = __PACKAGE__->new;
55 1   33     6 $NEED_CHCP = $self->os->is_winnt && $ENV{PROMPT};
56 1         11 my @probe = $self->probe;
57              
58 1         6 $self->_init_encoding;
59              
60 1         12 my $tb = Text::Table->new( q{}, q{} );
61 1         593 $tb->load( @probe );
62              
63 1 50       1801 print "\n", $tb or croak "Unable to orint to STDOUT: $!";
64 1         28756 return;
65             }
66              
67             sub probe {
68 1     1 1 2 my $self = shift;
69 1         3 my @rv = eval { $self->_probe(); };
  1         4  
70 1 50       5 croak "Error fetching information: $@" if $@;
71 1         8 return @rv;
72             }
73              
74             sub _init_encoding {
75 1     1   2 my $self = shift;
76 1 50       5 if ( $NEED_CHCP ) {
77             ## no critic (InputOutput::ProhibitBacktickOperators)
78 0         0 chomp($OLDCP = (split /:\s?/xms, qx(chcp))[LAST_ELEMENT]);
79             # try to change the command line encoding to unicode
80 0 0       0 _chcp( CP_UTF8 ) if $OLDCP;
81 0         0 if ( NEW_PERL ) {
82 0         0 my $eok = eval q{ binmode STDOUT, ':utf8'; 1; };
83             }
84             }
85 1         3 return;
86             }
87              
88             sub _probe {
89 1     1   3 my $self = shift;
90 1         4 my $meta = $self->meta;
91 1         5 my $NA = $self->NA;
92 1         6 my $i = $self->info;
93 1         4 my $os = $self->os;
94 1         6 my $pt = $os->product_type;
95 1         7 my $proc = $self->_processors;
96 1         19 my $tz = $os->tz;
97 1         228 my $driver = 'Sys::Info::Driver::' . OSID;
98 1         31 my @rv;
99              
100 1         25 push @rv,
101             [ 'Sys::Info Version' => Sys::Info->VERSION ],
102             [ sprintf( '%s Driver Version', OSID ) => $driver->VERSION ],
103             [ 'Perl Version' => $i->perl_long ],
104             [ 'Host Name' => $os->host_name ],
105             [ 'OS Name' => $self->_os_name ],
106             [ 'OS Version' => $self->_os_version ],
107             ;
108              
109 1         99 my $manu = $meta->{manufacturer};
110 1         3 my $bt = $meta->{build_type};
111              
112 1 50       7 push @rv, [ 'OS Manufacturer' => $manu ] if $manu;
113 1 50       4 push @rv, [ 'OS Configuration' => $pt ] if $pt;
114 1 50       4 push @rv, [ 'OS Build Type' => $bt ] if $bt;
115              
116 1         6 $self->_bitness( \@rv );
117 1         6 $self->_current_user( \@rv );
118 1         1298 $self->_registered( \@rv, $meta );
119              
120 1         16 my $pid = $meta->{product_id};
121 1         12 my $tick = $os->tick_count;
122 1         160 my $st = $meta->{system_type};
123              
124 1 50       5 push @rv, [ 'Product ID' => $pid ] if $pid;
125              
126 1         7 $self->_install_date( \@rv );
127              
128 1 50       9 push @rv, [ 'System Up Time' => elapsed($tick) ] if $tick;
129              
130 1         1714 $self->_manufacturer( \@rv, $meta );
131              
132 1 50       15 push @rv, [ 'System Type' => $st ] if $st;
133 1 50       5 push @rv, [ 'Processor(s)' => $proc ] if $proc;
134              
135 1         6 $self->_proc_meta( \@rv );
136 1         7 $self->_bios_version( \@rv );
137 1         5 $self->_directories( \@rv, $meta );
138              
139 1         4 my $loc = $self->{LOCALE};
140              
141 1 50       14 push @rv, [ 'System Locale' => $loc ] if $loc;
142 1 50       6 push @rv, [ 'Input Locale' => $loc ] if $loc;
143 1 50       6 push @rv, [ 'Time Zone' => $tz ] if $tz;
144              
145 1         6 $self->_memory( \@rv, $meta );
146 1         4 $self->_vm( \@rv );
147              
148 1         21 my $domain = $os->domain_name;
149 1         172 my $logon = $os->logon_server;
150 1         8 my $ip = $os->ip;
151 1         9191 my $page = $meta->{page_file_path};
152              
153 1 50       9 push @rv, [ 'Page File Location(s)' => $page ] if $page;
154 1 50       6 push @rv, [ 'Domain' => $domain ] if $domain;
155 1 50       6 push @rv, [ 'Logon Server' => $logon ] if $logon;
156 1 50       6 push @rv, [ 'IP Address' => $ip ] if $ip;
157              
158 1         8 $self->_cdkey( \@rv );
159              
160 1         29 return @rv;
161             }
162              
163             sub _registered {
164 1     1   3 my($self, $rv, $meta) = @_;
165 1 50       4 return if ! $self->os->is_windows;
166 0         0 my $owner = $meta->{owner};
167 0         0 my $org = $meta->{organization};
168 0 0       0 push @{ $rv }, [ 'Registered Owner' => $owner ] if $owner;
  0         0  
169 0 0       0 push @{ $rv }, [ 'Registered Organization' => $org ] if $org;
  0         0  
170 0         0 return;
171             }
172              
173             sub _directories {
174 1     1   3 my($self, $rv, $meta) = @_;
175 1         2 my $win = $meta->{windows_dir};
176 1         3 my $sys = $meta->{system_dir};
177 1         3 my $boot = $meta->{boot_device};
178 1 50       4 push @{ $rv }, [ 'Windows Directory' => $win ] if $win;
  0         0  
179 1 50       3 push @{ $rv }, [ 'System Directory' => $sys ] if $sys;
  0         0  
180 1 50       3 push @{ $rv }, [ 'Boot Device' => $boot ] if $boot;
  0         0  
181 1         3 return;
182             }
183              
184             sub _manufacturer {
185 1     1   4 my($self, $rv, $meta) = @_;
186 1 50       10 return if ! $self->os->is_windows;
187 0         0 my $manu = $meta->{system_manufacturer};
188 0         0 my $model = $meta->{system_model};
189 0 0       0 push @{ $rv }, [ 'System Manufacturer' => $manu ] if $manu;
  0         0  
190 0 0       0 push @{ $rv }, [ 'System Model' => $model ] if $model;
  0         0  
191 0         0 return;
192             }
193              
194             sub _cdkey {
195 1     1   4 my($self, $rv) = @_;
196 1         7 my $os = $self->os;
197 1 50       6 return if ! $os->is_windows;
198              
199 0         0 my $cdkey = $os->cdkey;
200 0         0 my $okey = $self->_office_cdkey;
201 0 0       0 push @{ $rv }, [ 'Windows CD Key' => $cdkey ] if $cdkey;
  0         0  
202 0 0       0 push @{ $rv }, [ 'Microsoft Office CD Key' => $okey ] if $okey;
  0         0  
203 0         0 return;
204             }
205              
206             sub _current_user {
207 1     1   3 my($self, $rv_ref) = @_;
208 1         4 my $os = $self->os;
209 1   50     9 my $user = $os->login_name || return;
210 0         0 my $real = $os->login_name( real => 1 );
211              
212 0 0 0     0 return if ! $user || ! $real;
213              
214 0 0 0     0 my $display = $real && ($real ne $user) ? qq{$real ($user)} : $user;
215 0 0       0 $display .= $os->is_root ? q{ is an administrator} : q{};
216 0         0 push @{ $rv_ref }, [ 'Current User', $display ];
  0         0  
217              
218 0         0 return;
219             }
220              
221             sub _proc_meta {
222 1     1   2 my $self = shift;
223 1         2 my $data = shift;
224 1         5 my @cpu = $self->cpu->identify;
225 1   50     29 my $prop = $cpu[0] || {};
226 1         5 my $load = $self->cpu->load;
227 1         213 my $L1 = $prop->{L1_cache}{max_cache_size};
228 1         4 my $L2 = $prop->{L2_cache}{max_cache_size};
229 1         3 my $sock = $prop->{socket_designation};
230 1         3 my $id = $prop->{processor_id};
231 1         3 my @rv;
232              
233             my $check_lc = sub {
234 2   50 2   9 my $ref = shift || return;
235 2 100       3 return if ! ${ $ref };
  2         8  
236 1 50       3 ${ $ref } .= q{ KB} if ${ $ref } !~ m{\sKB\z}xms;
  0         0  
  1         9  
237 1         2 return;
238 1         10 };
239              
240 1         4 $check_lc->( \$L1 );
241 1         3 $check_lc->( \$L2 );
242              
243 1 50       6 push @rv, qq{Load : $load} if $load;
244 1 50       5 push @rv, qq{L1 Cache: $L1} if $L1;
245 1 50       6 push @rv, qq{L2 Cache: $L2} if $L2;
246 1 50       5 push @rv, qq{Package : $sock} if $sock;
247 1 50       4 push @rv, qq{ID : $id} if $id;
248              
249 1         4 my $buf = q{ } x 2**2;
250 1         4 push @{$data}, [ q{ }, $buf . $_ ] for @rv;
  2         9  
251 1         10 return;
252             }
253              
254             sub _processors {
255 1     1   3 my $self = shift;
256 1         5 my $cpu = $self->cpu;
257 1         6 my $name = scalar $cpu->identify;
258 1         4866 my $rv = sprintf '%s ~%sMHz', $name, $cpu->speed;
259 1         40 $rv =~ s{\s+}{ }xmsg;
260 1         5 return $rv;
261             }
262              
263             sub _memory {
264 1     1   2 my($self, $rv, $meta) = @_;
265 1         9 push @{ $rv },
  4         85  
266             map {
267 1         2 [ $_->[0], $self->_mb( $_->[1] ) ]
268             }
269             [ 'Total Physical Memory' => $meta->{physical_memory_total} ],
270             [ 'Available Physical Memory' => $meta->{physical_memory_available} ],
271             [ 'Virtual Memory: Max Size' => $meta->{page_file_total} ],
272             [ 'Virtual Memory: Available' => $meta->{page_file_available} ],
273             ;
274 1         20 return;
275             }
276              
277             sub _vm {
278 1     1   3 my($self, $rv_ref) = @_;
279 1   50     4 my $tot = $self->meta->{page_file_total} || return;
280 1   50     4 my $av = $self->meta->{page_file_available} || return;
281 1         3 push @{ $rv_ref },
  1         12  
282             [ 'Virtual Memory: In Use' => $self->_mb( $tot - $av ) ]
283             ;
284 1         21 return;
285             }
286              
287             sub _mb {
288 5     5   11 my $self = shift;
289 5   50     13 my $kb = shift || return $self->NA;
290 5         12 return $self->fhb->base2( $kb, 2 );
291             }
292              
293             sub _os_name {
294 1     1   79 my $self = shift;
295 1         6 return $self->os->name( long => 1, edition => 1 );
296             }
297              
298             sub _os_version {
299 1     1   30 my $self = shift;
300 1         4 my $os = $self->os;
301 1         10 return $os->version . q{.} . $os->build;
302             }
303              
304             sub _office_cdkey {
305 0     0   0 my $self = shift;
306 0         0 my @office = $self->os->cdkey( office => 1 );
307 0 0       0 return @office ? $office[0] : undef;
308             }
309              
310             sub _bitness {
311 1     1   2 my($self, $rv_ref) = @_;
312 1   50     4 my $cpu = $self->cpu->bitness || q{??};
313 1   50     63 my $os = $self->os->bitness || q{??};
314 1         22 push @{ $rv_ref }, [ 'Running on' => qq{${cpu}bit CPU & ${os}bit OS} ];
  1         6  
315 1         4 return;
316             }
317              
318             sub _install_date {
319 1     1   2 my($self, $rv_ref) = @_;
320 1   50     6 my $date = $self->meta->{install_date} || return;
321 1         3 push @{ $rv_ref }, [ 'Original Install Date' => scalar localtime $date ];
  1         40  
322 1         2 return;
323             }
324              
325             sub _bios_version {
326 1     1   2 my($self, $rv_ref) = @_;
327 1         2 local $@;
328 1         4 my $bv = eval { $self->info->device('bios')->version; };
  1         5  
329 1 50 33     813 return if $@ || ! $bv;
330 0           push @{ $rv_ref }, [ 'BIOS Version' => $bv ];
  0            
331 0           return;
332             }
333              
334             1;
335              
336             __END__