Astro-SpaceTrack

 view release on metacpan or  search on metacpan

eg/SpaceTrackTk  view on Meta::CPAN

#!/usr/local/bin/perl

use 5.006002;

use strict;
use warnings;

use Astro::SpaceTrack qw{ :ref };
use IO::File;
use Tk;
use Tk::Pane;

our $VERSION = '0.182';

my @pad = qw{ -padx 5 -pady 5 };	# Standard cell padding

# Instantiate the Space Track accesor class.
my $st = Astro::SpaceTrack->new( @ARGV );

# Display the banner text if desired.
banner();

# Display the main window.
main_window();


# Display the banner text if desired, and wait for the user to dismiss
# it.
sub banner {

    $st->getv( 'banner' ) or return;

    my $mw = MainWindow->new( -title => 'Front Matter' );
    my $text = "SpaceTrackTk $VERSION" . $st->banner->content();
    $text =~ s/ \A \s+ //smx;
    $text =~ s/ \s+ \z //smx;
    $mw->Label( -text => $text )->pack( -side => 'top', @pad );
    $mw->Button( -text => 'OK', -command => sub { $mw->destroy() } )->
	pack( -side => 'bottom', @pad );

    MainLoop();

    return 1;
}

sub grid_args {
    my ( $hash, %arg ) = @_;
    my %merged = %{ $hash };
    foreach my $key ( keys %arg ) {
	$merged{$key} = $arg{$key};
    }
    my @rslt;
    while ( my ( $key, $val ) = each %merged ) {
	push @rslt, "-$key", $val;
    }
    exists $hash->{column}
	and $hash->{column} += ( $merged{columnspan} || 1 );
    return @rslt;
}

sub grid_new {
    my ( $row ) = @_;
    defined $row or $row = 0;
    return { row => $row, column => 0, padx => 5, pady => 5 };
}

sub grid_next_row {
    my ( $hash, $row ) = @_;
    if ( defined $row ) {
	$hash->{row} = $row;
    } else {
	$hash->{row}++;
    }
    $hash->{column} = 0;
    return;
}

# Main window
sub main_window {

    my %data;	# Data
    my %widget;	# Widget references

    $widget{main_window} = MainWindow->new(
	-title => 'Retrieve satellite orbital data' );

    # Set up the data frame.
    my $df = $widget{data_frame} = $widget{main_window}->Frame->pack(
	-side => 'top', @pad );

    # Create the data source label and widget, but don't put them in the
    # data frame yet.
    $widget{data_source_label} = $df->Label( -text => 'Data source:' );
    $widget{data_source_widget} = $df->Optionmenu(
	-variable => \$data{data_source},
	-command => sub { load_data_frame( \%widget, \%data ) },
    );
    load_data_source_widget( \%widget );

    # Set up the pushbuttons

    my @buttons;
    $widget{main_buttons} = \@buttons;

    my $bf = $widget{main_window}->Frame->pack(
	-side => 'bottom', @pad );
    my $bg = grid_new();

    push @buttons, $bf->Button(
	-text => 'Exit',
	-command => sub {
	    $widget{main_window}->destroy()
	}
    )->grid( grid_args( $bg ) );

    push @buttons, $bf->Button(
	-text => 'View data ...',

eg/SpaceTrackTk  view on Meta::CPAN

		},
		variable => '-variable',
	    },
	    Entry => {
		default => {
		    -relief => 'sunken',
		},
	    },
	);
    }

    my $settings;

    sub settings {
	my ( $widget, $data ) = @_;

	$settings and Exists( $settings ) and do {
	    $settings->raise();
	    return;
	};

	my %current = map { $_ => $st->getv( $_ ) } qw{ 
	    max_range password username identity verbose verify_hostname
	    webcmd
	};
	my %old = %current;

	$settings = $widget->{main_window}->Toplevel(
	    -title => 'Settings' );

	my $sg = grid_new();

	foreach (
	    'Access',
	    [ username => 'User Name:' ],
	    [ password => 'Password:', Entry => -show => '*' ],
	    [ identity => 'Identity from file:', 'Checkbutton' ],
	    'General',
	    [ max_range => 'Maximum range:' ],
	    [ verbose => 'Verbose Errors:', 'Checkbutton' ],
	    [ verify_hostname => 'Verify Host Name:', 'Checkbutton' ],
	    [ webcmd => 'Web Command:' ],
	) {
	    if ( ARRAY_REF eq ref $_ ) {
		my ( $name, $label, $entry, %args ) = @{ $_ };
		defined $entry or $entry = 'Entry';
		if ( $info{$entry}{default} ) {
		    while(  my ( $key, $val ) = each %{
			    $info{$entry}{default} } ) {
			exists $args{$key}
			    or $args{$key} = $val;
		    }
		}
		my $variable = $info{$entry}{variable} || '-textvariable';
		$settings->Label( -text => $label )->grid(
		    grid_args( $sg, sticky => 'e' ));
		$settings->$entry( %args, $variable => \$current{$name} )->grid(
		    grid_args( $sg, sticky => 'w' ) );
	    } else {
		$settings->Label( -text => $_ )->grid(
		    grid_args( $sg, columnspan => 2, sticky => 'ew' ) );
	    }

	    grid_next_row( $sg );
	}

	my $bf = $settings->Frame()->grid(
	    grid_args( $sg, columnspan => 2, sticky => 'ew' ) );
	my $bg = grid_new();

	$bf->Button( -text => 'Save', -command => sub {
		my $re_login;
		foreach my $key ( keys %current ) {
		    no warnings qw{ uninitialized };
		    $current{$key} eq $old{$key} and next;
		    if ( $key eq 'identity' ) {
			if ( $current{$key} ) {
			    $re_login = 1;
			} else {
			    $st->set( username => '', password => '' );
			    $st->logout();
			}
		    } else {
			$re_login ||= $authen{$key};
		    }
		    $st->set( $key => $current{$key} );
		}
		if ( $re_login ) {
		    my $rslt = $st->login();
		    $rslt->is_success() or do {
			$widget->{main_window}->messageBox(
			    -icon => 'error', -type => 'OK',
			    -title => 'Login failure',
			    -message => $rslt->status_line
			);
			return;
		    };
		    load_data_source_widget( $widget );
		    load_data_frame( $widget, $data );
		}
		$settings->destroy();
	    } )->grid( grid_args( $bg ) );

	$bf->Button( -text => 'Cancel', -command => sub {
		$settings->destroy();
		return;
	    } )->grid( grid_args( $bg ) );

	return;
    }
}

sub amsat_panel {
    my ( $widget, $data ) = @_;

    my $dg = grid_new( 1 );

    include_common_names( $widget, $data, $dg );

    return;
}

sub box_score_panel {
##  my ( $widget, $data ) = @_;		# Arguments unused
    return;
}

# Adjust the data panel to request Celestrak data.

eg/SpaceTrackTk  view on Meta::CPAN

	# whether we think we have a valid Space Track login cookie.
	$widget->{data_source_widget}->options( $options[
		$st->_check_cookie_generic( 2 ) ? 0 : 1
	    ]
	);
	return;
    }

}

# Retrieve the desired data.
sub retrieve {
    my ( $widget, $data ) = @_;
    my $source = $data->{data_source};
    my @args;
    if ( my $handler = __PACKAGE__->can( $source . '_args' ) ) {
	@args = $handler->( $data );
    } elsif ( defined $data->{$source} ) {
	@args = $data->{$source};
    }
#   warn "Debug - \$st->$source( ", join( ', ', map { "'$_'" } @args ), ' )';
#   use JSON;
#   warn "Debug - \$data is ", to_json( $data, { pretty => 1 } ), ' ';
    my ( $error );
    if ( my $rslt = eval {
	    local $SIG{__WARN__} = sub {
		( my $msg = $_[0] ) =~
		    s/ \S+ \s+ \S* SpaceTrackTk .* //smx;
		$msg =~ s/ \s+ / /smxg;
		$widget->{main_window}->messageBox( -icon => 'warning',
		    -type => 'OK', -title => 'Data fetch warning',
		    -message => $msg,
		);
	    };
	    $st->$source( @args );
	} ) {
	$rslt->is_success()
	    and return ( $rslt->content(), $source, @args );
	$error = $rslt->status_line();
    } else {
	$error = $@ || 'An unknown error occurred';
    }
    $widget->{main_window}->messageBox( -icon => 'error', -type => 'OK',
	-title => 'Data fetch error',
	-message => $error,
    );
    return;
}

{

    my %tabbed;

    BEGIN {

	%tabbed = (
	    box_score => sub {
		my ( $hash ) = @_;
		if ( $hash->{row} == 0 && $hash->{column} > 0 &&
		    $hash->{column} < 9 ) {
		    return grid_args( $hash, columnspan => 4 );
		} else {
		    return grid_args( $hash );
		}
	    },
	    search => \&grid_args,
	);
    }

    sub view_window {
	my ( $widget, $title, $content ) = @_;

	my $vw = $widget->{main_window}->Toplevel(
	    -title => $title,
	    -borderwidth => 8,
	);

	if ( my $grid_args = $tabbed{ $st->content_type() } ) {

	    my $vf = $vw->Scrolled(
		Frame => -scrollbars => 'osoe',
		-width => 600, -height => 400,
	    )->pack( -expand => 1, -fill => 'both' );

	    my $vg = {
		row => 0, column => 0,
		sticky => 'nsew',
		ipadx => 2, ipady => 2,
	    };

	    my @lo = (
		-relief => 'sunken',
		-justify => 'left',
		-wraplength => '20m',
	    );

	    my $loc = 0;
	    while ( $content =~ m/ ( \t | \r \n? | \n ) /smxg ) {
		$vf->Label(
		    -text => substr( $content, $loc, $-[0] - $loc ),
		    @lo,
		)->grid( $grid_args->( $vg ) );
		$loc = $+[0];
		"\t" eq $1 or grid_next_row( $vg );
	    }

	    $loc < length $content
		and $vf->Label(
		    -text => substr( $content, $loc ),
		    @lo,
		)->grid( $grid_args->( $vg ) );

	} else {

	    my $tx = $vw->Scrolled( 'Text',
		-relief => 'sunken',
		-scrollbars => 'oe',
	    )->pack( -expand => 1, -fill => 'both' );
	    $tx->insert( '0.0', $content );

	}



( run in 0.847 second using v1.01-cache-2.11-cpan-2398b32b56e )