Ok, thx, hippo. That's a good start. What I'm finding as I knock the cobwebs off scripts is that I had left things unfinished, and the problem with my heavily-google-dependent scripts was that I hadn't loaded the data, so google didn't have a response.
Another variety of google coming up with weird things is like this:
fritz@laptop:~/Documents$ ./1.lys.pl
Subroutine get_logger redefined at ./1.lys.pl line 47.
INFO: ./1.lys.pl
INFO: return from the google is -30 meters
INFO: Lysychansk on 2022-10-11T03:22:31 (1665476551 seconds unix-epoch
+) timezone: -0500 (lat: 38.4324101, lon: 48.9207881) at height -28 m
+eters
INFO: Object Azimuth Elevation
INFO: Jupiter 19.4268573032889 -50.7078930524939
INFO: Moon 336.298782353501 -36.1827200711628
INFO: Saturn 79.8122077165904 -38.9955330829549
INFO: return from the google is 821 meters
INFO: in the 'Ho on 2022-10-11T03:22:31 (1665433351 seconds unix-epoch
+) timezone: +0700 (lat: 43.61, lon: -116.2) at height 823 meters
INFO: Object Azimuth Elevation
INFO: Jupiter 36.2621632578313 -41.0584802357843
INFO: Moon 1.03055134306704 -36.9777514240792
INFO: Saturn 86.7497259872478 -27.6215597186519
fritz@laptop:~/Documents$
bliako may differ with me, but I think it is within their reach to have a valid number for the altitude of this hill, but they don't publish it so as not to be used the people who are targeting civilians, as they did today with approximately 85 missiles.
Script here for interested parties:
#!/usr/bin/perl
use v5.030; # strictness implied
use warnings;
use feature qw[ signatures ];
no warnings qw[ experimental::signatures ];
use Astro::Coord::ECI::Utils 'deg2rad';
use Astro::Coords;
use Astro::MoonPhase;
use Astro::Telescope;
use Data::Dumper;
use DateTime;
use DateTime::Format::ISO8601;
use DateTime::TimeZone;
use Log::Log4perl;
use Try::Tiny;
our $debug = 0;
my $time_str = "03:22:31";
my $alt = 0;
my $date_str = "2022-10-11";
my @events = (
{
"name" => "Lysychansk",
"date" => $date_str,
"time" => $time_str,
"location" => { lon => 48.9207881, lat => 38.4324101},
},
{
"name" => "in the 'Ho",
"date" => $date_str,
"time" => $time_str,
"location" => { lon => -116.2, lat => 43.61 },
},
);
# Not wanting to divine the configuration file for Log::Log4perl, modu
+le used in
# the query. Better for SSCCE considerations. thx parv
{
package Log::Log4perl;
sub get_logger ($pkg) { return bless [], $pkg; }
sub show (@arg) { warn @arg, "\n"; }
sub debug ( $ignore, @rest ) { show( 'DEBUG: ', @rest ); }
sub info ( $ignore, @rest ) { show( 'INFO: ', @rest ); }
sub warn ( $ignore, @rest ) { show( 'WARNING: ', @rest ); }
sub error ( $ignore, @rest ) { die 'ERROR: ', @rest, "\n"; }
}
my $logger = Log::Log4perl->get_logger();
$logger->info("$0");
## event loop
for my $event (@events) {
my $epoch = parse_event($event);
## determine altitude
# usage:
die unless exists $event->{location}; # restriction
my $return = get_elevation_from_coordinates( $event->{location}->{la
+t},
$event->{location}->{lon}, $debug );
$logger->info("return from the google is $return meters");
my $observer = $return + 2; #(most people stand)
$logger->info( event2str($event) . " at height $observer meters" );
$logger->info("Object\tAzimuth\t\tElevation");
for my $name (qw/Jupiter Moon Saturn/) {
my $planet = Astro::Coords->new( planet => $name );
# use DateTime
my $date = DateTime->from_epoch( epoch => $epoch, time_zone => 'UT
+C' );
$planet->datetime($date);
$planet->telescope(
Astro::Telescope->new(
Name => $event->{name},
Long => deg2rad( $event->{location}->{lon} ),
Lat => deg2rad( $event->{location}->{lat} ),
Alt => $observer, #meters above
+sea level
)
);
my $az = $planet->az( format => 'deg' );
my $el = $planet->el( format => 'deg' );
$logger->info("$name\t$az\t\t$el");
}
## end planets loop
}
## end event loop
sub event2str {
my $event = shift;
if ( !exists $event->{_is_parsed} ) {
warn "event has not been parsed, just dumping it...";
print Dump($event);
}
my $str =
$event->{name} . " on "
. $event->{datetime} . " ("
. $event->{datetime}->epoch
. " seconds unix-epoch)"
. " timezone: "
. $event->{datetime}->time_zone->name;
if ( exists $event->{location} ) {
if ( ref( $event->{location} ) eq 'HASH' ) {
$str .=
" (lat: "
. $event->{location}->{lat}
. ", lon: "
. $event->{location}->{lon} . ")";
}
else { $str .= "(" . $event->{location} . ")" }
}
return $str;
}
sub parse_event {
my $event = shift;
$debug //= 0;
if ( !exists $event->{date} ) { die "date field is missing from even
+t." }
my $datestr = $event->{date};
die "event does not have a 'name' field, please specify one, anythin
+g really."
unless exists $event->{name};
my $timestr = "00:00:01";
if ( exists $event->{time} ) {
$timestr = $event->{time};
print "event2epoch(): setting time to '$timestr' ...\n"
if $debug > 0;
die "time '$timestr' is not valid, it must be in the form 'hh:mm:s
+s'."
unless $timestr =~ /^\d{2}:\d{2}:\d{2}$/;
}
else { $event->{time} = $timestr }
my $isostr = $datestr . 'T' . $timestr;
my $dt = DateTime::Format::ISO8601->parse_datetime($isostr);
die "failed to parse date '$isostr', check date and time fields."
unless defined $dt;
$event->{datetime} = $dt;
my $tzstr = 'UTC';
if ( exists $event->{timezone} ) {
$tzstr = $event->{timezone};
print
"event2epoch(): found a timezone via 'timezone' field as '$tzstr' (tha
+t does not mean it is valid) ...\n"
if $debug > 0;
}
elsif ( exists $event->{location} ) {
my $loc = $event->{location};
if ( ( ref($loc) eq '' ) && ( $loc =~ /^[a-zA-Z]$/ ) ) {
# we have a location string
my @alltzs = DateTime::TimeZone->all_names;
my $tzstr;
for (@alltzs) {
if ( $_ =~ /$loc/i ) { $tzstr = $_; last }
}
die
"event's location can not be converted to a timezone, consider specify
+ing the 'timezone' directly or setting 'location' coordinates with: \
+[lat,lon\]."
unless $tzstr;
print
"event2epoch(): setting timezone via 'location' name to '$timestr' ...
+\n"
if $debug > 0;
}
elsif ( ( ref($loc) eq 'HASH' )
&& ( exists $loc->{lat} )
&& ( exists $loc->{lon} ) )
{
# we have a [lat,lon] array for location
require Geo::Location::TimeZone;
my $gltzobj = Geo::Location::TimeZone->new();
$tzstr = $gltzobj->lookup( lat => $loc->{lat}, lon => $loc->{lon
+} );
if ( !$tzstr ) {
die "timezone lookup from location coordinates lat:"
. $loc->{lat}
. ", lon:"
. $loc->{lon}
. " has failed.";
}
print "event2epoch(): setting timezone via 'location' coordinate
+s lat:"
. $loc->{lat}
. ", lon:"
. $loc->{lon}
. " ...\n"
if $debug > 0;
}
}
if ($tzstr) {
print "event2epoch(): deduced timezone to '$tzstr' and setting it
+...\n"
if $debug > 0;
try {
$dt->set_time_zone($tzstr)
}
catch {
die "$_\n failed to set the timezone '$tzstr', is it valid?"
}
}
$event->{_is_parsed} = 1;
$event->{epoch} = $dt->epoch;
return $event->{epoch};
}
sub get_elevation_from_coordinates {
my ( $lat, $lon, $debug ) = @_;
use LWP::UserAgent;
use HTTP::Request;
use Data::Roundtrip;
$debug //= 0;
my $ua = LWP::UserAgent->new( agent =>
'Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox
+/78.0', );
my $response;
my $payload =
'latitude='
. $lat
. '&longitude='
. $lon
. '&application_max_assets_mtime=1559625591';
my $payloadlen = length($payload);
# this request was translated from Curl command-line
# by [Corion]'s https://corion.net/curl2lwp.psgi
my $req = HTTP::Request->new(
'POST' =>
'https://www.mapcoordinates.net/admin/component/edit/Vpc_MapCoordinate
+s_Advanced_GoogleMapCoords_Component/Component/json-get-elevation',
[
'Connection' => 'keep-alive',
'Accept' => '*/*',
'Accept-Encoding' => 'gzip, x-gzip, deflate, x-bzip2, bzip2',
'Accept-Language' => 'en-US,en;q=0.5',
# 'Host' => 'www.mapcoordinates.net:443',
'Referer' => 'https://www.mapcoordinates.net/en',
'User-Agent' =>
'Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firef
+ox/78.0',
'Content-Length' => $payloadlen,
'Content-Type' => 'application/x-www-form-urlencoded; charse
+t=UTF-8',
'DNT' => '1',
'Origin' => 'https://www.mapcoordinates.net',
'X-Requested-With' => 'XMLHttpRequest'
],
$payload
);
die "call to HTTP::Request has failed" unless $req;
if ( $debug > 0 ) {
$logger->debug(
"$0 : $payload\n$0 : sending above payload, of $payloadlen bytes
+...");
}
$response = $ua->request($req);
die "Error fetching: " . $response->status_line
unless $response->is_success;
my $content = $response->decoded_content;
my $data = Data::Roundtrip::json2perl($content);
die "failed to parse received data:\n$content\n"
unless exists $data->{'elevation'};
return $data->{'elevation'};
}
__END__
fritz@laptop:~/Documents$
I'm still curious about the question of whether an email from Berlin to Moscow goes through. Does anyone know? (I'm fresh out of people in Moscow I talk to. Hi Ed, if you read this.)
Also, can someone enumerate instances of google misusing people's information or the potential to do so? I talk about needing to have some rapport/realpolitik with giant evil corporations, but this is a step too far for me.
Is there a treatment out there from sysadmins about why an organization should have one document on a secure site and send out links to that one secure document as opposed to sending it as a mass email attachment where 60% of the recipients have no context for it whatsoever?
Do well-intentioned people create a polluted digital spam ocean by sending mass email with attachments?