aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@ubuntu.com>2019-02-09 01:20:57 -0500
committerLibravatarUnit 193 <unit193@ubuntu.com>2019-02-09 01:20:57 -0500
commit006fad9eb918b42f1050434c9a4ba1610d100028 (patch)
tree9a26f5cf45bc48053bcaba7e6f55fc6f2addf0a9
parent35e3c788c9f74d2f566371241bda0f4d6f40ea76 (diff)
parent38bfd820d2274c2c11fb2153dfe06bf8db7fd722 (diff)
downloadinxi-006fad9eb918b42f1050434c9a4ba1610d100028.tar.bz2
inxi-006fad9eb918b42f1050434c9a4ba1610d100028.tar.xz
inxi-006fad9eb918b42f1050434c9a4ba1610d100028.tar.zst
Update upstream source from tag 'upstream/3.0.32-1'
Update to upstream version '3.0.32-1' with Debian dir a33cc6d25ffa1ceac91318d72a100ca1fc6b5894
-rwxr-xr-xinxi403
-rw-r--r--inxi.176
-rw-r--r--inxi.changelog86
3 files changed, 448 insertions, 117 deletions
diff --git a/inxi b/inxi
index 99c469a..b039e5c 100755
--- a/inxi
+++ b/inxi
@@ -1,6 +1,6 @@
#!/usr/bin/env perl
## infobash: Copyright (C) 2005-2007 Michiel de Boer aka locsmif
-## inxi: Copyright (C) 2008-2018 Harald Hope
+## inxi: Copyright (C) 2008-2019 Harald Hope
## Additional features (C) Scott Rogers - kde, cpu info
## Further fixes (listed as known): Horst Tritremmel <hjt at sidux.com>
## Steven Barrett (aka: damentz) - usb audio patch; swap percent used patch
@@ -31,8 +31,8 @@ use POSIX qw(uname strftime ttyname);
## INXI INFO ##
my $self_name='inxi';
-my $self_version='3.0.30';
-my $self_date='2018-12-31';
+my $self_version='3.0.32';
+my $self_date='2019-02-07';
my $self_patch='00';
## END INXI INFO ##
@@ -72,7 +72,7 @@ $b_fake_bsd,$b_fake_dboot,$b_fake_dmidecode,$b_fake_pciconf,$b_fake_sysctl,
$b_fake_usbdevs,$b_force_display,$b_gpudata,$b_irc,
$b_log,$b_log_colors,$b_log_full,$b_man,$b_mem,$b_mips,
$b_pci,$b_pci_tool,$b_ppc,$b_proc_partitions,$b_ps_gui,
-$b_root,$b_running_in_display,
+$b_root,$b_running_in_display,$b_skip_dig,
$b_slot_tool,$b_soc_audio,$b_soc_gfx,$b_soc_net,$b_soc_timer,$b_sparc,
$b_sudo,$b_sysctl,$b_usb,$b_usb_check,$b_usb_sys,$b_usb_tool,$b_wmctrl);
## Disk checks
@@ -81,11 +81,11 @@ $b_label_uuid,$b_lsblk,$b_partitions,$b_raid);
my ($b_sysctl_disk,$b_update,$b_weather) = (1,1,1);
## System
-my ($bsd_type,$language,$os,$pci_tool,$device_vm) = ('','','','','');
+my ($bsd_type,$device_vm,$language,$os,$pci_tool,$wan_url) = ('','','','','','');
my ($bits_sys,$cpu_arch);
my ($cpu_sleep,$dl_timeout,$limit,$ps_cols,$ps_count) = (0.35,4,10,0,5);
my $sensors_cpu_nu = 0;
-my $weather_unit='mi';
+my ($dl_ua,$weather_source,$weather_unit) = ('s-tools/' . $self_name . '-',100,'mi');
## Tools
my ($display,$ftp_alt,$tty_session);
@@ -218,7 +218,7 @@ sub check_tools {
'dmidecode' => {
'action' => $action,
'missing' => 'Required program dmidecode not available',
- 'permissions' => 'Unable to run dmidecode. Are you root?',
+ 'permissions' => 'Unable to run dmidecode. Root privileges required.',
'smbios' => 'No SMBIOS data for dmidecode to process',
'no-data' => 'dmidecode is not allowed to read /dev/mem',
'unknown-error' => 'dmidecode was unable to generate data',
@@ -328,7 +328,6 @@ sub check_tools {
}
set_fake_tools() if $b_fake_bsd;
}
-
# args: 1 - desktop/app command for --version; 2 - search string;
# 3 - space print number; 4 - [optional] version arg: -v, version, etc
# 5 - [optional] exit first find 0/1; 6 - [optional] 0/1 stderr output
@@ -343,7 +342,7 @@ sub set_basics {
$b_irc = ( check_program('tty') && system('tty >/dev/null') ) ? 1 : 0;
# print "birc: $b_irc\n";
$b_display = ( $ENV{'DISPLAY'} ) ? 1 : 0;
- $b_root = ( $ENV{'HOME'} eq '/root' ) ? 1 : 0;
+ $b_root = $< == 0; # root UID 0, all others > 0
$dl{'dl'} = 'curl';
$dl{'curl'} = 1;
$dl{'tiny'} = 1; # note: two modules needed, tested for in set_downloader
@@ -1084,6 +1083,13 @@ sub get_config_item {
elsif ($key eq 'SENSORS_CPU_NO') {$sensors_cpu_nu = $val if is_int($val)}
elsif ($key eq 'SHOW_HOST' || $key eq 'B_SHOW_HOST') { $show{'host'} = $val if is_int($val)}
elsif ($key eq 'USB_SYS') {$b_usb_sys = $val if is_int($val)}
+ elsif ($key eq 'WAN_IP_URL') {
+ if ($val =~ /^(ht|f)tp[s]?:\//i){
+ $wan_url = $val;
+ $b_skip_dig = 1;
+ }
+ }
+ elsif ($key eq 'WEATHER_SOURCE') {$weather_source = $val if is_int($val)}
elsif ($key eq 'WEATHER_UNIT') {
$val = lc($val) if $val;
if ($val && $val =~ /^(c|f|cf|fc|i|m|im|mi)$/){
@@ -2152,10 +2158,11 @@ sub user_debug_test_1 {
#### -------------------------------------------------------------------
sub download_file {
- my ($type, $url, $file) = @_;
+ my ($type, $url, $file,$ua) = @_;
my ($cmd,$args,$timeout) = ('','','');
my $debug_data = '';
my $result = 1;
+ $ua = ($ua && $dl{'ua'}) ? $dl{'ua'} . $ua : '';
$dl{'no-ssl-opt'} ||= '';
$dl{'spider'} ||= '';
$file ||= 'N/A'; # to avoid debug error
@@ -2176,22 +2183,23 @@ sub download_file {
}
# But: 0 is success, and 1 is false for these
# when strings are returned, they will be taken as true
+ # urls must be " quoted in case special characters present
else {
if ($type eq 'stdout'){
$args = $dl{'stdout'};
- $cmd = "$dl{'dl'} $dl{'no-ssl-opt'} $timeout $args $url $dl{'null'}";
+ $cmd = "$dl{'dl'} $dl{'no-ssl-opt'} $ua $timeout $args \"$url\" $dl{'null'}";
$result = qx($cmd);
$debug_data = ($result) ? 'Success: stdout data not null.' : 'Download resulted in null data!';
}
elsif ($type eq 'file') {
$args = $dl{'file'};
- $cmd = "$dl{'dl'} $dl{'no-ssl-opt'} $timeout $args $file $url $dl{'null'}";
+ $cmd = "$dl{'dl'} $dl{'no-ssl-opt'} $ua $timeout $args $file \"$url\" $dl{'null'}";
system($cmd);
$result = ($?) ? 0 : 1; # reverse these into Perl t/f
$debug_data = $result;
}
elsif ( $dl{'dl'} eq 'wget' && $type eq 'spider'){
- $cmd = "$dl{'dl'} $dl{'no-ssl-opt'} $timeout $dl{'spider'} $url";
+ $cmd = "$dl{'dl'} $dl{'no-ssl-opt'} $ua $timeout $dl{'spider'} \"$url\"";
system($cmd);
$result = ($?) ? 0 : 1; # reverse these into Perl t/f
$debug_data = $result;
@@ -2247,6 +2255,7 @@ sub get_file {
sub set_downloader {
eval $start if $b_log;
+ my $quiet = '';
$dl{'no-ssl'} = '';
$dl{'null'} = '';
$dl{'spider'} = '';
@@ -2271,25 +2280,30 @@ sub set_downloader {
$dl{'timeout'} = '';
}
elsif ( $dl{'curl'} && check_program('curl') ){
+ $quiet = '-s ' if !$test[1];
$dl{'dl'} = 'curl';
- $dl{'file'} = ' -L -s -o ';
+ $dl{'file'} = " -L ${quiet}-o ";
$dl{'no-ssl'} = ' --insecure';
- $dl{'stdout'} = ' -L -s ';
+ $dl{'stdout'} = " -L ${quiet}";
$dl{'timeout'} = ' -y ';
+ $dl{'ua'} = ' -A ' . $dl_ua;
}
elsif ($dl{'wget'} && check_program('wget') ){
+ $quiet = '-q ' if !$test[1];
$dl{'dl'} = 'wget';
- $dl{'file'} = ' -q -O ';
+ $dl{'file'} = " ${quiet}-O ";
$dl{'no-ssl'} = ' --no-check-certificate';
- $dl{'spider'} = ' -q --spider';
- $dl{'stdout'} = ' -q -O -';
+ $dl{'spider'} = " ${quiet}--spider";
+ $dl{'stdout'} = " $quiet -O -";
$dl{'timeout'} = ' -T ';
+ $dl{'ua'} = ' -U ' . $dl_ua;
}
elsif ($dl{'fetch'} && check_program('fetch')){
+ $quiet = '-q ' if !$test[1];
$dl{'dl'} = 'fetch';
- $dl{'file'} = ' -q -o ';
+ $dl{'file'} = " ${quiet}-o ";
$dl{'no-ssl'} = ' --no-verify-peer';
- $dl{'stdout'} = ' -q -o -';
+ $dl{'stdout'} = " ${quiet}-o -";
$dl{'timeout'} = ' -T ';
}
elsif ( $bsd_type eq 'openbsd' && check_program('ftp') ){
@@ -3683,7 +3697,7 @@ sub update_man {
return 0;
}
if ( ! -w $man_file_location ){
- print "Cannot write to $man_file_location! Are you root?\n";
+ print "Cannot write to $man_file_location! Root privileges required.\n";
print "Unable to continue: $man_file_location\n";
return 0;
}
@@ -4056,6 +4070,16 @@ sub get_options{
else {
error_handler('distro-block', $opt);
} },
+ 'ws|weather-source:s' => sub {
+ my ($opt,$arg) = @_;
+ # let api processor handle checks if valid, this
+ # future proofs this
+ if ($arg =~ /^[0-9]$/){
+ $weather_source = $arg;
+ }
+ else {
+ error_handler('bad-arg',$opt,$arg);
+ } },
'weather-unit:s' => sub {
my ($opt,$arg) = @_;
$arg ||= '';
@@ -4325,6 +4349,15 @@ sub get_options{
$b_usb_tool = 1 },
'V|version' => sub {
$b_version = 1 },
+ 'wan-ip-url:s' => sub {
+ my ($opt,$arg) = @_;
+ if ($arg && $arg =~ /^(f|ht)tp[s]?:\/\//){
+ $wan_url = $arg;
+ $b_skip_dig = 1
+ }
+ else {
+ error_handler('bad-arg', $opt, $arg);
+ }},
'wm' => sub {
$b_wmctrl = 1 },
'<>' => sub {
@@ -4334,7 +4367,7 @@ sub get_options{
## run all these after so that we can change widths, downloaders, etc
eval $end if $b_log;
CheckRecommends::run() if $b_recommends;
- set_downloader() if $b_downloader;
+ set_downloader() if $b_downloader || $wan_url; # sets for either config or arg here
show_version() if $b_version;
show_options() if $b_help;
$b_man = 0 if (!$b_use_man || $b_no_man_force);
@@ -4519,10 +4552,12 @@ sub show_options {
['1', '-w', '--weather', "Local weather data/time. To check an alternate
location, see -W."],
['1', '-W', '--weather-location', "[location] Supported options for
- [location]: postal code; city, state/country; latitude, longitude.
+ [location]: postal code[,country]; city, state/country; latitude, longitude.
Only use if you want the weather somewhere other than the machine running
$self_name. Use only ASCII characters, replace spaces in city/state/country
names with '+'. Example:^$self_name^-W^new+york,ny"],
+ ['1', '', '--weather-source', "[0-9] Change weather data source. 0 uses
+ a legacy source internally. 1-3 generally active, 4-9 check. See man."],
['1', '', '--weather-unit', "Set weather units to metric (m), imperial (i),
metric/imperial (mi), or imperial/metric (im)."],
);
@@ -4567,7 +4602,7 @@ sub show_options {
push @data, @rows;
if ( $b_weather ){
@rows = (['2', '-w -W', '', "Wind speed and direction, humidity, pressure,
- and (-w only) time zone." ]);
+ and time zone, if available." ]);
push @data, @rows;
}
@rows = (
@@ -4598,7 +4633,8 @@ sub show_options {
);
push @data, @rows;
if ( $b_weather ){
- @rows = (['2', '-w -W', '', "Wind chill, dew point, heat index, if available." ]);
+ @rows = (['2', '-w -W', '', "Snow, rain, precipitation, (last observed hour),
+ cloud cover, wind chill, dew point, heat index, if available." ]);
push @data, @rows;
}
@rows = (
@@ -4627,7 +4663,7 @@ sub show_options {
push @data, @rows;
if ( $b_weather ){
@rows = (['2', '-w -W', '', "Location (uses -z/irc filter), weather observation
- time, altitude (shows extra lines for data where relevant)." ] );
+ time, altitude, sunrise/sunset, if available." ] );
push @data, @rows;
}
@rows = (
@@ -4714,9 +4750,14 @@ sub show_options {
you want a specific output width. Always put this option first in an option list."],
['1', '', '--usb-sys', "Force USB data to use /sys as data source (Linux only)." ],
['1', '', '--usb-tool', "Force USB data to use lsusb as data source (Linux only)." ],
+ ['1', '', '--wan-ip-url', "[URL] Skips dig, uses supplied URL for WAN IP (-i).
+ URL output must end in the IP address. See man.
+ Example:^$self_name^-i^--wan-ip-url^https://yoursite.com/ip.php" ],
['1', '', '--wm', "Force wm: to use wmctrl as data source. Default uses ps." ],
['0', '', '', $line ],
['0', '', '', "Debugging Options:" ],
+ ['1', '', '--dbg', "Specific debuggers, change often. Only 1 is constant:" ],
+ ['2', '1', '', "Show downloader output. Turns off quiet mode." ],
['1', '', '--debug', "Triggers debugging modes." ],
['2', '1-3', '', "On screen debugger output." ],
['2', '10', '', "Basic logging." ],
@@ -5404,7 +5445,7 @@ sub row_defaults {
'root-required' => "<root required>",
'sensors-data-ipmi' => "No ipmi sensors data was found.",
'sensors-data-linux' => "No sensors data was found. Is sensors configured?",
- 'sensors-ipmi-root' => "Unable to run ipmi sensors. Are you root?",
+ 'sensors-ipmi-root' => "Unable to run ipmi sensors. Root privileges required.",
'tool-missing' => "<missing $id>",
'unmounted-data' => "No unmounted partitions found.",
'unmounted-data-bsd' => "No unmounted partition data found for this BSD system.",
@@ -5413,6 +5454,7 @@ sub row_defaults {
'unknown-desktop-version' => "ERR-101",
'unknown-dev' => "ERR-102",
'unknown-shell' => "ERR-100",
+ 'weather-error' => "Error in weather data: $id",
'weather-null' => "No $id found. Internet connection working?",
'xdpyinfo-missing' => '<xdpyinfo missing>',
);
@@ -7883,7 +7925,11 @@ sub cpu_arch {
elsif ( $model =~ /^(3A|3E)$/ ) {$arch = 'Ivy Bridge'}
elsif ( $model =~ /^(3C|3F|45|46)$/ ) {$arch = 'Haswell'}
elsif ( $model =~ /^(3D|47|4F|56)$/ ) {$arch = 'Broadwell'}
- elsif ( $model =~ /^(4E|55)$/ ) {$arch = 'Skylake'} # had 9E
+ elsif ( $model =~ /^(4E)$/ ) {$arch = 'Skylake'} # had 9E, cascade lake also 55
+ # need to find stepping for cl, guessing stepping 4 is last for sl
+ elsif ( $model =~ /^(55)$/ ) {
+ if ($stepping > 4){$arch = 'Cascade Lake'}
+ else {$arch = 'Skylake'} }
elsif ( $model =~ /^(5C|5F)$/ ) {$arch = 'Goldmont'}
elsif ( $model =~ /^(5E)$/ ) {$arch = 'Skylake-S'}
elsif ( $model =~ /^(4C)$/ ) {$arch = 'Airmont'}
@@ -7896,9 +7942,9 @@ sub cpu_arch {
elsif ( $model =~ /^(57)$/ ) {$arch = 'Knights Landing'}
elsif ( $model =~ /^(66)$/ ) {$arch = 'Cannon Lake'}
elsif ( $model =~ /^(85)$/ ) {$arch = 'Knights Mill'}
- elsif ( $model =~ /^(865)$/ ) {$arch = 'Tremont'}
+ elsif ( $model =~ /^(86)$/ ) {$arch = 'Tremont'}
# coming: alder lake; amber lake; cannonlake; cascade lake; coffee lake;
- # granite rapids; icelake; meteor lake; saphire rapids; tigerlake,
+ # cooper lake; granite rapids; icelake; meteor lake; saphire rapids; tigerlake,
}
# itanium 1 family 7 all recalled
elsif ($family eq 'B'){
@@ -8678,7 +8724,7 @@ sub device_vendor {
## These go first because they are the most likely and common ##
['(Crucial|^(FC)?CT|-CT|^M4\b)','Crucial','Crucial',''],
['^(INTEL|SSD(PAM|SA2))','^INTEL','Intel',''],
- ['(KINGSTON|DataTraveler|^SMS|^SHS|^SUV|^Ultimate CF)','KINGSTON','Kingston',''], # maybe SHS: SHSS37A SKC SUV
+ ['(KINGSTON|DataTraveler|DT\s?(DUO|Microduo|101)|^SMS|^SHS|^SUV|^Ultimate CF)','KINGSTON','Kingston',''], # maybe SHS: SHSS37A SKC SUV
# must come before samsung MU. NOTE: toshiba can have: TOSHIBA_MK6475GSX: mush: MKNSSDCR120GB_
['(^MKN|Mushkin)','Mushkin','Mushkin',''], # MKNS
# MU = Multiple_Flash_Reader too risky: |M[UZ][^L] HD103SI HD start risky
@@ -8697,14 +8743,14 @@ sub device_vendor {
['^ATP','^ATP[\s\-]','ATP',''],
# Force MP500
['^(Corsair|Force\s|Voyager)','^Corsair','Corsair',''],
- ['^(FUJITSU|MHV|MP)','^FUJITSU','Fujitsu',''],
+ ['^(FUJITSU|MH[VY]|MP)','^FUJITSU','Fujitsu',''],
# note: 2012: wdc bought hgst
- ['^(HGST|Touro)','^HGST','HGST (Hitachi)',''], # HGST HUA
+ ['^(HGST|Touro|5450)','^HGST','HGST (Hitachi)',''], # HGST HUA
['^(Hitachi|HD[ST]|DK[0-9]|IC|HT|HU)','^Hitachi','Hitachi',''],
['^Hoodisk','^Hoodisk','Hoodisk',''],
# vb: VB0250EAVER but clashes with vbox; HP_SSD_S700_120G ;GB0500EAFYL GB starter too generic?
['^(HP\b|MB0|G[BJ]0|v[0-9]{3}[ow])','^HP','HP',''],
- ['^(LSD|Lexar|JumpDrive)','^Lexar','Lexar',''], # mmc-LEXAR_0xb016546c
+ ['^(LSD|Lexar|JumpDrive|JD\s?Firefly)','^Lexar','Lexar',''], # mmc-LEXAR_0xb016546c; JD Firefly;
# OCZSSD2-2VTXE120G is OCZ-VERTEX2_3.5
['^(OCZ|APOC|D2|DEN|DEN|DRSAK|EC188|FTNC|GFGC|MANG|MMOC|NIMC|NIMR|PSIR|TALOS2|TMSC|TRSAK)','^OCZ[\s\-]','OCZ',''],
['^OWC','^OWC[\s\-]','OWC',''],
@@ -8729,6 +8775,9 @@ sub device_vendor {
['^CHN\b','','Zheino',''],
['^Colorful\b','^Colorful','Colorful',''],
['^CSD','^CSD','CSD',''],
+ ['^(Dane-?Elec|Z Mate)','^Dane-?Elec','DaneElec',''],
+ # Daplink vfs is an ARM software thing
+ ['^DeLOCK','^Delock(\s?products)?','Delock',''],
['^DGM','^DGM\b','DGM',''],
['^DIGITAL\s?FILM','DIGITAL\s?FILM','Digital Film',''],
['^DREVO\b','^DREVO','Drevo',''],
@@ -8746,7 +8795,7 @@ sub device_vendor {
['^Gigabyte','^Gigabyte','Gigabyte',''], # SSD
['^Gigastone','^Gigastone','Gigastone',''],
['^Gloway','^Gloway','Gloway',''],
- ['^GOODRAM','^GOODRAM','GOODRAM',''],
+ ['^(GOODRAM|IR SSD)','^GOODRAM','GOODRAM',''],
# supertalent also has FM: |FM
['^(G[\.]?SKILL)','^G[\.]?SKILL','G.SKILL',''],
['^HUAWEI','^HUAWEI','Huawei',''],
@@ -8818,6 +8867,7 @@ sub device_vendor {
['^(TDK|TF[1-9][0-9])','^TDK','TDK',''],
['^TEAC','^TEAC','TEAC',''],
['^TEAM','^TEAM( Group)?','Team',''],
+ ['^Tigo','^Tigo','Tigo',''],
['^TopSunligt','^TopSunligt','TopSunligt',''], # is this a typo? hard to know
['^TopSunlight','^TopSunlight','TopSunlight',''],
['^(TS|Transcend|JetFlash)','^Transcend','Transcend',''],
@@ -9944,7 +9994,7 @@ sub machine_data_soc {
$temp[1] = main::dmi_cleaner($temp[1]);
$soc_machine{'device'} = main::cleaner($temp[1]);
}
- elsif (/^(system type)\s*:/i){
+ elsif (/^(system type|model)\s*:/i){
@temp = split /\s*:\s*/, $_;
$temp[1] = main::dmi_cleaner($temp[1]);
$soc_machine{'model'} = main::cleaner($temp[1]);
@@ -10743,19 +10793,22 @@ sub if_ip {
# dig +short +time=1 +tries=1 myip.opendns.com. A @208.67.222.222
sub wan_ip {
eval $start if $b_log;
- my (@data,$ip);
+ my (@data,$ip,$ua);
my $num = 0;
# time: 0.06 - 0.07 seconds
- if (my $program = main::check_program('dig')){
+ if (!$b_skip_dig && (my $program = main::check_program('dig') )){
$ip = (main::grabber("$program +short +time=1 +tries=1 myip.opendns.com \@resolver1.opendns.com 2>/dev/null"))[0];
}
else {
# note: tests: akamai: 0.055 - 0.065 icanhazip.com: 0.177 0.164
# smxi: 0.525, so almost 10x slower. Dig is fast too
# leaving smxi as last test because I know it will always be up.
- my @urls = qw( http://whatismyip.akamai.com/ http://icanhazip.com/ https://smxi.org/opt/ip.php);
+ # --wan-ip-url replaces values with user supplied arg
+ my @urls = (!$wan_url) ? qw( http://whatismyip.akamai.com/
+ http://icanhazip.com/ https://smxi.org/opt/ip.php) : ($wan_url);
foreach (@urls){
- $ip = main::download_file('stdout',$_);
+ $ua = 'ip' if $_ =~ /smxi/;
+ $ip = main::download_file('stdout',$_,'',$ua);
if ($ip){
# print "$_\n";
chomp $ip;
@@ -15302,7 +15355,7 @@ sub get {
sub create_output {
eval $start if $b_log;
my $num = 0;
- my (@data,@location,@rows,%weather,);
+ my (@data,@location,@rows,$value,%weather,);
my ($conditions) = ('NA');
if ($show{'weather-location'}){
my $location_string;
@@ -15331,6 +15384,11 @@ sub create_output {
}
}
%weather = get_weather(@location);
+ if ($weather{'error'}) {
+ return @rows = ({
+ main::key($num++,'Message') => main::row_defaults('weather-error',$weather{'error'}),
+ });
+ }
if (!$weather{'weather'}) {
return @rows = ({
main::key($num++,'Message') => main::row_defaults('weather-null','weather data'),
@@ -15348,32 +15406,63 @@ sub create_output {
my $wind = wind_output($weather{'wind'},$weather{'wind-direction'},$weather{'wind-mph'},$weather{'wind-ms'},
$weather{'wind-gust-mph'},$weather{'wind-gust-ms'});
$rows[0]{main::key($num++,'Wind')} = $wind;
- $rows[0]{main::key($num++,'Humidity')} = $weather{'humidity'};
+ if ($extra > 1){
+ if (defined $weather{'cloud-cover'}){
+ $rows[0]{main::key($num++,'Cloud Cover')} = $weather{'cloud-cover'} . '%';
+ }
+ if ($weather{'precip-1h-mm'} && defined $weather{'precip-1h-in'} ){
+ $value = unit_output('',$weather{'precip-1h-mm'},'mm',$weather{'precip-1h-in'},'in');
+ $rows[0]{main::key($num++,'Precipitation')} = $value;
+ }
+ if ($weather{'rain-1h-mm'} && defined $weather{'rain-1h-in'} ){
+ $value = unit_output('',$weather{'rain-1h-mm'},'mm',$weather{'rain-1h-in'},'in');
+ $rows[0]{main::key($num++,'Rain')} = $value;
+ }
+ if ($weather{'snow-1h-mm'} && defined $weather{'snow-1h-in'} ){
+ $value = unit_output('',$weather{'snow-1h-mm'},'mm',$weather{'snow-1h-in'},'in');
+ $rows[0]{main::key($num++,'Snow')} = $value;
+ }
+ }
+ $rows[0]{main::key($num++,'Humidity')} = $weather{'humidity'} . '%';
+ if ($extra > 1){
+ if ($weather{'dewpoint'} || (defined $weather{'dewpoint-c'} && defined $weather{'dewpoint-f'})){
+ $value = unit_output($weather{'dewpoint'},$weather{'dewpoint-c'},'C',$weather{'dewpoint-f'},'F');
+ $rows[0]{main::key($num++,'Dew Point')} = $value;
+ }
+ }
$rows[0]{main::key($num++,'Pressure')} = $pressure;
}
if ($extra > 1){
- if ($weather{'heat-index'}){
- my $heat = unit_output($weather{'heat-index'},$weather{'heat-index-c'},'C',$weather{'heat-index-f'},'F');
- $rows[0]{main::key($num++,'Heat Index')} = $heat;
- }
- if ($weather{'windchill'}){
- my $chill = unit_output($weather{'windchill'},$weather{'windchill-c'},'C',$weather{'windchill-f'},'F');
- $rows[0]{main::key($num++,'Wind Chill')} = $chill ;
+ if ($weather{'heat-index'} || (defined $weather{'heat-index-c'} && defined $weather{'heat-index-f'})){
+ $value = unit_output($weather{'heat-index'},$weather{'heat-index-c'},'C',$weather{'heat-index-f'},'F');
+ $rows[0]{main::key($num++,'Heat Index')} = $value;
}
- if ($weather{'dewpoint'}){
- my $dew = unit_output($weather{'dewpoint'},$weather{'dewpoint-c'},'C',$weather{'dewpoint-f'},'F');
- $rows[0]{main::key($num++,'Dew Point')} = $dew;
+ if ($weather{'windchill'} || (defined $weather{'windchill-c'} && defined $weather{'windchill-f'})){
+ $value = unit_output($weather{'windchill'},$weather{'windchill-c'},'C',$weather{'windchill-f'},'F');
+ $rows[0]{main::key($num++,'Wind Chill')} = $value;
}
}
if ($extra > 2){
if (!$show{'filter'}){
- $rows[0]{main::key($num++,'Location')} = $location[1];
- $rows[0]{main::key($num++,'altitude')} = elevation_output($weather{'elevation-m'},$weather{'elevation-ft'});
+ $rows[0]{main::key($num++,'Location')} = complete_location($location[1],$weather{'city'},$weather{'state'},$weather{'country'});
+ if ($weather{'elevation-m'} || $weather{'elevation-ft'}){
+ $rows[0]{main::key($num++,'altitude')} = elevation_output($weather{'elevation-m'},$weather{'elevation-ft'});
+ }
}
}
$rows[0]{main::key($num++,'Current Time')} = $weather{'date-time'};
if ($extra > 2){
+ $weather{'observation-time-local'} = 'N/A' if !$weather{'observation-time-local'};
$rows[0]{main::key($num++,'Observation Time')} = $weather{'observation-time-local'};
+ if ($weather{'sunrise'}){
+ $rows[0]{main::key($num++,'Sunrise')} = $weather{'sunrise'};
+ }
+ if ($weather{'sunset'}){
+ $rows[0]{main::key($num++,'Sunset')} = $weather{'sunset'};
+ }
+ }
+ if ($weather{'api-source'}){
+ $rows[0]{main::key($num++,'Source')} = $weather{'api-source'};
}
eval $end if $b_log;
return @rows;
@@ -15407,16 +15496,16 @@ sub unit_output {
eval $start if $b_log;
my ($primary,$metric,$m_unit,$imperial,$i_unit) = @_;
my $result = '';
- if ($metric && $imperial && $weather_unit eq 'mi' ){
+ if (defined $metric && defined $imperial && $weather_unit eq 'mi' ){
$result = "$metric $m_unit ($imperial $i_unit)";
}
- elsif ($metric && $imperial && $weather_unit eq 'im' ){
+ elsif (defined $metric && defined $imperial && $weather_unit eq 'im' ){
$result = "$imperial $i_unit ($metric $m_unit)";
}
- elsif ($metric && $weather_unit eq 'm' ){
+ elsif (defined $metric && $weather_unit eq 'm' ){
$result = "$metric $m_unit";
}
- elsif ($imperial && $weather_unit eq 'i' ){
+ elsif (defined $imperial && $weather_unit eq 'i' ){
$result = "$imperial $i_unit";
}
elsif ($primary){
@@ -15436,21 +15525,21 @@ sub wind_output {
$gust_mph = undef if $gust_mph && $mph && $mph eq $gust_mph;
$gust_ms = undef if $gust_ms && $ms && $ms eq $gust_ms;
# calculate and round, order matters so that rounding only happens after math done
- $ms = 0.44704 * $mph if $mph && !$ms;
- $mph = $ms * 2.23694 if $ms && !$mph;
- $kmh = sprintf("%.0f", 18 * $ms / 5) if $ms;
- $ms = sprintf("%.1f", $ms ) if $ms; # very low mph speeds yield 0, which is wrong
- $mph = sprintf("%.0f", $mph) if $mph;
+ $ms = 0.44704 * $mph if defined $mph && !defined $ms;
+ $mph = $ms * 2.23694 if defined $ms && !defined $mph;
+ $kmh = sprintf("%.0f", 18 * $ms / 5) if defined $ms;
+ $ms = sprintf("%.1f", $ms ) if defined $ms; # very low mph speeds yield 0, which is wrong
+ $mph = sprintf("%.0f", $mph) if defined $mph;
$gust_ms = 0.44704 * $gust_mph if $gust_mph && !$gust_ms;
$gust_kmh = 18 * $gust_ms / 5 if $gust_ms;
$gust_mph = $gust_ms * 2.23694 if $gust_ms && !$gust_mph;
$gust_mph = sprintf("%.0f", $gust_mph) if $gust_mph;
$gust_kmh = sprintf("%.0f", $gust_kmh) if $gust_kmh;
$gust_ms = sprintf("%.0f", $gust_ms ) if $gust_ms;
- if (!$mph && $primary){
+ if (!defined $mph && $primary){
$result = $primary;
}
- elsif ($mph && $direction ){
+ elsif (defined $mph && defined $direction ){
if ( $weather_unit eq 'mi' ){
$result = "from $direction at $ms $m_unit ($kmh $km_unit, $mph $i_unit)";
}
@@ -15495,48 +15584,33 @@ sub get_weather {
my $loc_name = lc($location[0]);
$loc_name =~ s/-\/|\s|,/-/g;
$loc_name =~ s/--/-/g;
- my $file_cached = "$user_data_dir/weather-$loc_name.txt";
+ my $file_cached = "$user_data_dir/weather-$loc_name-$weather_source.txt";
if (-f $file_cached){
@weather_data = main::reader($file_cached);
$freshness = (split /\^\^/, $weather_data[0])[1];
#print "$now:$freshness\n";
}
- if (!$freshness || $freshness < ($now - 90) ) {
- @weather_data = (); # reset so we don't write the previous data to file!!
- my $url = "http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=$location[0]";
- my $temp;
-# {
-# #my $file2 = "$ENV{'HOME'}/bin/scripts/inxi/data/weather/weather-1.xml";
-# # my $file2 = "$ENV{'HOME'}/bin/scripts/inxi/data/weather/feed-oslo-1.xml";
-# local $/;
-# my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/weather/weather-1.xml";
-# open my $fh, '<', $file or die "can't open $file: $!";
-# $temp = <$fh>;
-# }
- $temp = main::download_file('stdout',$url);
- $temp =~ s/\r|\n\n/\n/g;
- my @weather_temp = split /\n/, $temp;
- foreach (@weather_temp){
- chomp $_;
- $_ =~ s/<\/[^>]+>//;
- $_ =~ s/.*icon.*|\r//g;
- $_ =~ s/\s\s/ /g;
- $_ =~ s/^\s+|\s+$//g;
- $_ =~ s/>/^^/;
- $_ =~ s/^<|NA$//g;
- $_ =~ s/^(current|credit|terms|image|title|link|.*_url).*//;
- push @weather_data, $_ if $_ !~ /^\s*$/;
- }
- unshift (@weather_data,("timestamp^^$now"));
- main::writer($file_cached,\@weather_data);
- #print "$file_cached: download/cleaned\n";
+ if (!$freshness || $freshness < ($now - 60) ) {
+ @weather_data = download_weather($now,$file_cached,@location);
}
#print join "\n", @weather_data, "\n";
# NOTE: because temps can be 0, we can't do if value tests
foreach (@weather_data){
my @working = split /\s*\^\^\s*/,$_;
next if ! defined $working[1] || $working[1] eq '';
- if ( $working[0] eq 'dewpoint_string' ){
+ if ( $working[0] eq 'api_source' ){
+ $weather{'api-source'} = $working[1];
+ }
+ elsif ( $working[0] eq 'city' ){
+ $weather{'city'} = $working[1];
+ }
+ elsif ( $working[0] eq 'cloud_cover' ){
+ $weather{'cloud-cover'} = $working[1];
+ }
+ elsif ( $working[0] eq 'country' ){
+ $weather{'country'} = $working[1];
+ }
+ elsif ( $working[0] eq 'dewpoint_string' ){
$weather{'dewpoint'} = $working[1];
$working[1] =~ /^([0-9\.]+)\sF\s\(([0-9\.]+)\sC\)/;
$weather{'dewpoint-c'} = $2;;
@@ -15548,12 +15622,15 @@ sub get_weather {
elsif ( $working[0] eq 'dewpoint_f' ){
$weather{'dewpoint-f'} = $working[1];
}
- # there are two elevations, we want the first one
+ # WU: there are two elevations, we want the first one
elsif (!$weather{'elevation-m'} && $working[0] eq 'elevation'){
# note: bug in source data uses ft for meters, not 100% of time, but usually
$weather{'elevation-m'} = $working[1];
$weather{'elevation-m'} =~ s/\s*(ft|m).*$//;
}
+ elsif ( $working[0] eq 'error' ){
+ $weather{'error'} = $working[1];
+ }
elsif ( $working[0] eq 'heat_index_string' ){
$weather{'heat-index'} = $working[1];
$working[1] =~ /^([0-9\.]+)\sF\s\(([0-9\.]+)\sC\)/;
@@ -15567,6 +15644,7 @@ sub get_weather {
$weather{'heat-index-f'} = $working[1];
}
elsif ( $working[0] eq 'relative_humidity' ){
+ $working[1] =~ s/%$//;
$weather{'humidity'} = $working[1];
}
elsif ( $working[0] eq 'local_time' ){
@@ -15576,7 +15654,7 @@ sub get_weather {
$weather{'local-epoch'} = $working[1];
}
elsif ( $working[0] eq 'observation_time_rfc822' ){
- $weather{'observation-time-gmt'} = $working[1];
+ $weather{'observation-time-rfc822'} = $working[1];
}
elsif ( $working[0] eq 'observation_epoch' ){
$weather{'observation-epoch'} = $working[1];
@@ -15585,6 +15663,12 @@ sub get_weather {
$weather{'observation-time-local'} = $working[1];
$weather{'observation-time-local'} =~ s/Last Updated on //;
}
+ elsif ( $working[0] eq 'precip_mm' ){
+ $weather{'precip-1h-mm'} = $working[1];
+ }
+ elsif ( $working[0] eq 'precip_in' ){
+ $weather{'precip-1h-in'} = $working[1];
+ }
elsif ( $working[0] eq 'pressure_string' ){
$weather{'pressure'} = $working[1];
}
@@ -15594,6 +15678,43 @@ sub get_weather {
elsif ( $working[0] eq 'pressure_in' ){
$weather{'pressure-in'} = $working[1];
}
+ elsif ( $working[0] eq 'rain_1h_mm' ){
+ $weather{'rain-1h-mm'} = $working[1];
+ }
+ elsif ( $working[0] eq 'rain_1h_in' ){
+ $weather{'rain-1h-in'} = $working[1];
+ }
+ elsif ( $working[0] eq 'snow_1h_mm' ){
+ $weather{'snow-1h-mm'} = $working[1];
+ }
+ elsif ( $working[0] eq 'snow_1h_in' ){
+ $weather{'snow-1h-in'} = $working[1];
+ }
+ elsif ( $working[0] eq 'state_name' ){
+ $weather{'state'} = $working[1];
+ }
+ elsif ( $working[0] eq 'sunrise' ){
+ if ($working[1]){
+ if ($working[1] !~ /^[0-9]+$/){
+ $weather{'sunrise'} = $working[1];
+ }
+ # trying to figure out remote time from UTC is too hard
+ elsif (!$show{'weather-location'}){
+ $weather{'sunrise'} = POSIX::strftime "%T", localtime($working[1]);
+ }
+ }
+ }
+ elsif ( $working[0] eq 'sunset' ){
+ if ($working[1]){
+ if ($working[1] !~ /^[0-9]+$/){
+ $weather{'sunset'} = $working[1];
+ }
+ # trying to figure out remote time from UTC is too hard
+ elsif (!$show{'weather-location'}){
+ $weather{'sunset'} = POSIX::strftime "%T", localtime($working[1]);
+ }
+ }
+ }
elsif ( $working[0] eq 'temperature_string' ){
$weather{'temp'} = $working[1];
$working[1] =~ /^([0-9\.]+)\sF\s\(([0-9\.]+)\sC\)/;
@@ -15609,6 +15730,9 @@ sub get_weather {
elsif ( $working[0] eq 'temp_c' ){
$weather{'temp-c'} = $working[1];
}
+ elsif ( $working[0] eq 'timezone' ){
+ $weather{'timezone'} = $working[1];
+ }
elsif ( $working[0] eq 'visibility' ){
$weather{'visibility'} = $working[1];
}
@@ -15656,14 +15780,26 @@ sub get_weather {
}
}
if ($show{'weather-location'}){
- $weather{'observation-time-local'} =~ /^(.*)\s([\S]+)$/;
- $tz = $2;
+ if ($weather{'observation-time-local'} &&
+ $weather{'observation-time-local'} =~ /^(.*)\s([a-z_]+\/[a-z_]+)$/i){
+ $tz = $2;
+ }
+ if (!$tz && $weather{'timezone'}){
+ $tz = $weather{'timezone'};
+ $weather{'observation-time-local'} .= ' (' . $weather{'timezone'} . ')' if $weather{'observation-time-local'};
+ }
# very clever trick, just make the system think it's in the
# remote timezone for this local block only
- local $ENV{'TZ'} = $tz;
+ local $ENV{'TZ'} = $tz if $tz;
$date_time = POSIX::strftime "%c", localtime();
$date_time = test_local_date($date_time,'','');
$weather{'date-time'} = $date_time;
+ # only wu has rfc822 value, and we want the original observation time then
+ if ($weather{'observation-epoch'} && $tz){
+ $date_time = POSIX::strftime "%Y-%m-%d %T ($tz %z)", localtime($weather{'observation-epoch'});
+ $date_time = test_local_date($date_time,$show{'weather-location'},$weather{'observation-epoch'});
+ $weather{'observation-time-local'} = $date_time;
+ }
}
else {
$date_time = POSIX::strftime "%c", localtime();
@@ -15680,6 +15816,50 @@ sub get_weather {
return %weather;
eval $end if $b_log;
}
+sub download_weather {
+ eval $start if $b_log;
+ my ($now,$file_cached,@location) = @_;
+ my (@weather,@weather_temp,$temp,$ua,$url);
+ if ($weather_source == 0){
+ $url = "http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=$location[0]";
+ }
+ else {
+ $url = "https://smxi.org/opt/xr2.php?loc=$location[0]&src=$weather_source";
+ }
+ $ua = 'weather' if $url =~ /smxi/;
+# {
+# #my $file2 = "$ENV{'HOME'}/bin/scripts/inxi/data/weather/weather-1.xml";
+# # my $file2 = "$ENV{'HOME'}/bin/scripts/inxi/data/weather/feed-oslo-1.xml";
+# local $/;
+# my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/weather/weather-1.xml";
+# open my $fh, '<', $file or die "can't open $file: $!";
+# $temp = <$fh>;
+# }
+ $temp = main::download_file('stdout',$url,'',$ua);
+ $temp =~ s/\r|\n\n/\n/g if $weather_source == 0;
+ @weather_temp = split /\n/, $temp;
+ if ($weather_source == 0){
+ foreach (@weather_temp){
+ chomp $_;
+ $_ =~ s/<\/[^>]+>//;
+ $_ =~ s/.*icon.*|\r//g;
+ $_ =~ s/\s\s/ /g;
+ $_ =~ s/^\s+|\s+$//g;
+ $_ =~ s/>/^^/;
+ $_ =~ s/^<|NA$//g;
+ $_ =~ s/^(current|credit|terms|image|title|link|.*_url).*//;
+ push @weather, $_ if $_ !~ /^\s*$/;
+ }
+ }
+ else {
+ @weather = @weather_temp;
+ }
+ unshift (@weather,("timestamp^^$now"));
+ main::writer($file_cached,\@weather);
+ #print "$file_cached: download/cleaned\n";
+ eval $end if $b_log;
+ return @weather;
+}
# resolve wide character issue, if detected, switch to iso
# date format, we won't try to be too clever here.
sub test_local_date {
@@ -15694,6 +15874,7 @@ sub test_local_date {
$date_time = POSIX::strftime "%Y-%m-%d %H:%M:%S", localtime();
}
}
+ $date_time =~ s/\s+$//;
#print "2: $date_time\n";
return $date_time;
}
@@ -15786,6 +15967,17 @@ sub get_location {
eval $end if $b_log;
return @location;
}
+sub complete_location {
+ eval $start if $b_log;
+ my ($location,$city,$state,$country) = @_;
+ if ($location && $location =~ /[\+\-0-9]/ && $city){
+ $location = $country . ', ' . $location if $country && $location !~ m|$country|i;
+ $location = $state . ', ' . $location if $state && $location !~ m|$state|i;
+ $location = $city . ', ' . $location;
+ }
+ eval $end if $b_log;
+ return $location;
+}
}
#### -------------------------------------------------------------------
@@ -16710,7 +16902,7 @@ sub get_linux_distro {
}
if ($extra > 0){
my $base_debian_version_distro = 'sidux';
- my $base_debian_version_osr = '\belive|lmde|neptune|parrot|pureos|sparky|tails';
+ my $base_debian_version_osr = '\belive|lmde|neptune|parrot|pureos|septor|sparky|tails';
my $base_default = 'antix-version|mx-version'; # osr has base ids
my $base_issue = 'bunsen'; # base only found in issue
my $base_manual = 'blankon|deepin|kali'; # synthesize, no direct data available
@@ -17410,12 +17602,15 @@ sub get_pci_vendor {
eval $start if $b_log;
my ($device, $subsystem) = @_;
return if !$subsystem;
- my ($vendor,$sep) = ('','');
+ my ($vendor,$sep,$temp) = ('','','');
# get rid of any [({ type characters that will make regex fail
$subsystem = regex_cleaner($subsystem);
my @data = split /\s+/, $subsystem;
+ # when using strings in patterns for regex have to escape them
foreach (@data){
- if ($device !~ /\b$_\b/){
+ $temp = $_;
+ $temp =~ s/(\+|\$|\?|\^|\*)/\\$1/g;
+ if ($device !~ m|\b$temp\b|){
$vendor .= $sep . $_;
$sep = ' ';
}
diff --git a/inxi.1 b/inxi.1
index 2380dcd..5429073 100644
--- a/inxi.1
+++ b/inxi.1
@@ -1,4 +1,4 @@
-.TH INXI 1 "2018\-12\-31" inxi "inxi manual"
+.TH INXI 1 "2019\-02\-07" inxi "inxi manual"
.SH NAME
inxi \- Command line system information script for console and IRC
.SH SYNOPSIS
@@ -446,15 +446,16 @@ optical drives.
.TP
.B \-v 6
\- Adds full mounted partition data (\fB\-p\fR), unmounted partition data (\fB\-o\fR),
-optical drive data (\fB\-d\fR), USB (\fB\-\-usb\fR); triggers \fB\-xx\fR extra data option.
+optical drive data (\fB\-d\fR), USB (\fB\-\-usb\fR); triggers \fB\-xx\fR extra data
+option.
.TP
.B \-v 7
\- Adds network IP data (\fB\-i\fR); triggers \fB\-xxx\fR
.TP
.B \-v 8
-\- All system data available. Adds Repos (\fB\-r\fR), PCI slots (\fB\-\-slots\fR), processes
-(\fB\-tcm\fR), admin (\fB\-\-admin\fR). Useful for testing output and to see what data
-you can get from your system.
+\- All system data available. Adds Repos (\fB\-r\fR), PCI slots (\fB\-\-slots\fR),
+processes (\fB\-tcm\fR), admin (\fB\-\-admin\fR). Useful for testing output and to
+see what data you can get from your system.
.TP
.B \-w\fR,\fB \-\-weather\fR
Adds weather line. Note, this depends on an unreliable API so it may not always
@@ -462,14 +463,28 @@ be working in the future. To get weather for an alternate location, use
\fB\-W\fR. See also \fB\-x\fR, \fB\-xx\fR, \fB\-xxx\fR options.
Please note that your distribution's maintainer may chose to disable this feature.
.TP
-.B \-W\fR,\fB \-\-weather\-location <location_string>\fR
-Get weather/time for an alternate location. Accepts postal/zip code,
+.B \-W\fR, \fB\-\-weather\-location <location_string>\fR
+Get weather/time for an alternate location. Accepts postal/zip code[, country],
city,state pair, or latitude,longitude. Note: city/country/state names must not
-contain spaces. Replace spaces with '\fB+\fR' sign. Don't place spaces around any commas.
-Use only ASCII letters in city/state/country names, sorry.
+contain spaces. Replace spaces with '\fB+\fR' sign. Don't place spaces around
+any commas. Postal code is not reliable except for North America and maybe the UK.
+Try postal codes with and without country code added.
-Examples: \fB\-W 95623\fR OR \fB\-W Boston,MA\fR OR \fB\-W45.5234,\-122.6762\fR
-OR \fB\-W new+york,ny\fR OR \fB\-W bodo,norway\fR.
+Use only ASCII letters in city/state/country names.
+
+Examples: \fB\-W 95623,us\fR OR \fB\-W Boston,MA\fR OR
+\fB\-W 45.5234,\-122.6762\fR OR \fB\-W new+york,ny\fR OR \fB\-W bodo,norway\fR.
+.TP
+.B \-\-weather\-source\fR, \fB\-\-ws <unit>\fR
+[\fB0\-9\fR] Switches weather data source. 0 uses a legacy source which may vanish
+any day. \fB1\-9\fR use different remote sources. \fB2\fR may not support city /
+country names with spaces (even if you use the \fB+\fR sign instead of space).
+\fB3\fR offers pretty good data, but may not have all small city names for
+\fB\-W\fR.
+
+More data sources will be added as time permits, so try each one and
+see which you prefer. If you get unsupported source message, it means that number
+has not been implemented.
.TP
.B \-\-weather\-unit <unit>\fR
[\fBm\fR|\fBi\fR|\fBmi\fR|\fBim\fR] Sets weather units to metric (\fBm\fR), imperial (\fBi\fR),
@@ -747,7 +762,10 @@ if \fBps\fR tests fail to find data.
\- Adds vendor:chip id.
.TP
.B \-xx \-w\fR,\fB \-W\fR
-\- Adds wind chill, heat index, and dew point if any of these are available.
+\- Adds wind chill, heat index, and dew point, if available.
+
+\- Adds cloud cover, rain, snow, or precipitation (amount in previous hour
+to observation time), if available.
.TP
.B \-xxx \-A\fR
\- Adds, if present, serial number.
@@ -826,7 +844,8 @@ lxpanel, xfce4\-panel, lxqt\-panel, tint2, cairo-dock, trayer, and many others.
\- Adds, if available, USB speed in \fBMbits/s\fR or \fBGbits/s\fR.
.TP
.B \-xxx \-w\fR,\fB \-W\fR
-\- Adds location (city state country), altitude, weather observation time.
+\- Adds location (city state country), observation altitude (if available),
+weather observation time (if available), sunset/sunrise (if available).
.SH ADMIN EXTRA DATA OPTIONS
These options are triggered with \fB\-\-admin\fR or \fB\-a\fR. Admin options are
@@ -1041,6 +1060,18 @@ Forces the USB data generator to use \fBlsusb\fR as data source. Overrides
\fBUSB_SYS\fR in user configuration file(s).
.TP
+.B \-\-wan\-ip\-url [URL]\fR
+Force \fB\-i\fR to use supplied URL as WAN IP source. Overrides dig or
+default IP source urls. URL must start with http[s] or ftp.
+
+The IP address from the URL must be the last item on the last (non-empty) line
+of the page content source code.
+
+Same as configuration value (example):
+
+\fBWAN_IP_URL='https://mysite.com/ip.php'\fR
+
+.TP
.B \-\-wm\fR
Force \fBSystem\fR item \fBwm\fR to use \fBwmctrl\fR as data source,
override default \fBps\fR source.
@@ -1048,6 +1079,12 @@ override default \fBps\fR source.
.SH DEBUGGING OPTIONS
.TP
+.B \-\-dbg 1\fR
+\- Debug downloader failures. Turns off silent/quiet mode for curl, wget, and
+fetch. Shows more downloader action information. Shows some more information
+for Perl downloader.
+
+.TP
.B \-\-debug [1\-3]\fR
\- On screen debugger output. Output varies depending on current needs
Usually nothing changes.
@@ -1238,6 +1275,19 @@ above configuration page on smxi.org for full info.
\fBUSB_SYS\fR Forces all USB data to use \fB/sys\fR instead of \fBlsusb\fR.
+\fBWAN_IP_URL\fR Forces \fB\-i\fR to use supplied URL, and to not use dig (dig is
+generally much faster). URL must begin with http or ftp. Note that if you use this,
+the downloader set tests will run each time you start inxi whether a downloader feature
+is going to be used or not.
+
+The IP address from the URL must be the last item on the last (non-empty) line of
+the URL's page content source code.
+
+Same as \fB\-\-wan\-ip\-url [URL]\fR
+
+\fBWEATHER_SOURCE\fR Values: [\fB0-9\fR]. Same as \fB\-\-weather\-source\fR. Values
+4-9 are not currently supported, but this can change at any time.
+
\fBWEATHER_UNIT\fR Values: [\fBc\fR|\fBf\fR|\fBcf\fR|\fBfc\fR]. Same as \fB\-\-weather\-unit\fR.
.TP
diff --git a/inxi.changelog b/inxi.changelog
index 0bbbf42..c32598a 100644
--- a/inxi.changelog
+++ b/inxi.changelog
@@ -1,4 +1,90 @@
=====================================================================================
+Version: 3.0.32
+Patch: 00
+Date: 2019-02-07
+-----------------------------------
+Changes:
+-----------------------------------
+New version, new man. A few more modifications to weather.
+
+Fixes:
+1. In case with zero wind speed, it now shows zero, not N/A, as expected.
+
+Enhancements:
+1. Depending on weather source used:
+ * Shows precipitation, not rain/snow.
+ * Adds Sunrise/sunset (most sources do not have this)
+
+-----------------------------------
+-- Harald Hope - Thu, 07 Feb 2019 20:50:18 -0800
+
+=====================================================================================
+Version: 3.0.31
+Patch: 00
+Date: 2019-02-06
+-----------------------------------
+Changes:
+-----------------------------------
+New version, new man page. Big update! Get it in before your freeze!!
+
+Bugs:
+1. Maybe the vendor/product regex, which when + was used, would put out
+errors.
+2. Maybe Fix 4, since that could lead to incorrect behavior when sudo
+is involved depending on sudo configuration.
+3. BIG: current inxi weather will probably fail if not updated to this or
+newer versions!! Not an inxi bug per se, but your users will see it as one.
+
+Fixes:
+1. Fixed Patriot disk ID.
+2. Fixes for PPC board handling.
+3. Regex cleaner fixes, this could lead to error in special cases of product
+vendor names.
+4. crazy from frugalware pointed out that $b_root detection was flawed, and
+relied on a bad assumption, particularly for sudo. As usual, he's right, that
+is now corrected, and uses $< Perl native to determine UID.
+
+Enhancements:
+1. Added septor to Debian system base.
+2. Removed quiet filters for downloaders when using --dbg 1, now you see the
+entire download action for curl/wget downloads. This went along with
+issue # 174
+3. New feature: --wan-ip-url. This closed issue #174. Also has user config
+option: WAN_IP_URL as well to make changes permanent.
+4. Added --dbg 1 to man and help. The other --dbg options are random and can
+change, but --dbg 1 is always for downloading, so might as well tell people
+about it.
+5. To anticipate the loss of a major weather API, inxi is redone to use smxi.org
+based robust API. This also allows for a new switch, --weather-source (or --ws
+for shorter version), options 0-9, which will trigger different APIs on smxi.org.
+Added WEATHER_SOURCE configuration option as well. Note that 4-9 are not
+currently active. Also added in better error handling for weather.
+The main benefit here is that inxi is now largely agnostic to the weather APIs
+used, and those can be changed with no impact to inxi users who are running
+frozen pool inxi's, or who have not updated their inxi versions.
+
+NOTE: all inxi versions older than 3.0.31 will probably fail for weather
+quite soon. So update your inxi version in your repos!!
+6. More disk vendors IDs and matches. Thanks linuxlite hardware database.
+7. Going along with weather changes, added, if present, cloud cover, rain, and
+snow reports. Those are for previously observed hour.
+8. Small change to Intel CPU architecture, taking a guess on stepping for
+skylake/Cascade lake ID. Guessing if stepping is > 4, it's cascade lake. But
+could not find this documented, so it's a guess. At worst, it means that Cascade
+lake, which must be a later steppingi than 4, will not be ID'ed as skylake.
+9. Documentation updates for data sources.
+
+Changes:
+1. inxi now uses a new system to get weather data. There is no longer a risk
+of weather failing if the API used locally in inxi fails or goes away. This
+change should be largely invisible to casual users.
+2. In weather, moved dewpoint to be after humidity, which makes a little more
+sense.
+
+-----------------------------------
+-- Harald Hope - Wed, 06 Feb 2019 18:09:53 -0800
+
+=====================================================================================
Version: 3.0.30
Patch: 00
Date: 2018-12-31