Astro-SpaceTrack
view release on metacpan or search on metacpan
lib/Astro/SpaceTrack.pm view on Meta::CPAN
},
mccants => {
classified => {
name => 'Classified TLE file',
member => undef, # classfd.tle
spacetrack_type => 'orbit',
url => 'https://www.mmccants.org/tles/classfd.zip',
},
integrated => {
name => 'Integrated TLE file',
member => undef, # inttles.tle
spacetrack_type => 'orbit',
url => 'https://www.mmccants.org/tles/inttles.zip',
},
mcnames => {
name => 'Molczan-format magnitude file',
member => undef, # mcnames
spacetrack_type => 'molczan',
url => 'https://www.mmccants.org/tles/mcnames.zip',
},
# Removed 2025-12-15 or thereabouts
quicksat => {
name => 'Quicksat-format magnitude file',
member => undef, # qs.mag
spacetrack_type => 'quicksat',
url => 'https://www.mmccants.org/programs/qsmag.zip',
},
# Removed 2024-12-29.
#rcs => {
# name => 'McCants-format RCS data (404 2024-04-27)',
# member => undef, # rcs
# spacetrack_type => 'rcs.mccants',
# url => 'https://www.mmccants.org/catalogs/rcs.zip',
#},
vsnames => {
name => 'Molczan-format magnitude file (visual only)',
member => undef, # vsnames
spacetrack_type => 'molczan',
url => 'https://www.mmccants.org/tles/vsnames.zip',
},
},
spacetrack => [ # Numbered by space_track_version
undef, # No interface version 0
undef, # No interface version 1 any more
{ # Interface version 2 (REST)
# On Space Track "Recent ELSETs" tab
full => {
name => 'Full catalog',
# As of 2026-01-19
# https://www.space-track.org/basicspacedata/query/class/gp/EPOCH/%3Enow-30/orderby/NORAD_CAT_ID,EPOCH/format/3le
# We have to go through satcat to eliminate bodies that
# are not on orbit, since tle_latest includes bodies
# decayed in the last two years or so
# satcat => {},
tle => {
EPOCH => '>now-30',
},
# number => 1,
},
geosynchronous => { # GEO
name => 'Geosynchronous satellites',
# As of 2026-01-19
# https://www.space-track.org/basicspacedata/query/class/gp/EPOCH/%3Enow-30/MEAN_MOTION/0.99--1.01/ECCENTRICITY/%3C0.01/OBJECT_TYPE/payload/orderby/NORAD_CAT_ID,EPOCH/format/3le
# number => 3,
# We have to go through satcat to eliminate bodies that
# are not on orbit, since tle_latest includes bodies
# decayed in the last two years or so
# satcat => {
# PERIOD => '1425.6--1454.4'
# },
# Note that the v2 interface specimen query is
# PERIOD 1430--1450.
# The v1 definition is
# MEAN_MOTION 0.99--1.01
# ECCENTRICITY <0.01
# tle => {
# ECCENTRICITY => '<0.01',
## MEAN_MOTION => '0.99--1.01',
# },
tle => {
ECCENTRICITY => '<0.01',
EPOCH => '>now-30',
MEAN_MOTION => '0.99--1.01',
OBJECT_TYPE => 'payload',
},
},
medium_earth_orbit => { # MEO
name => 'Medium Earth Orbit',
# As of 2026-01-19
# https://www.space-track.org/basicspacedata/query/class/gp/EPOCH/%3Enow-30/MEAN_MOTION/1.8--2.39/ECCENTRICITY/%3C0.25/OBJECT_TYPE/payload/orderby/NORAD_CAT_ID,EPOCH/format/3le
tle => {
ECCENTRICITY => '<0.25',
EPOCH => '>now-30',
# The web page says '600 minutes <= Period <= 800
# minutes', but the query is in terms of mean
# motion.
MEAN_MOTION => '1.8--2.39',
OBJECT_TYPE => 'payload',
},
},
low_earth_orbit => { # LEO
name => 'Low Earth Orbit',
# As of 2026-01-19https://www.space-track.org/basicspacedata/query/class/gp/EPOCH/%3Enow-30/ECCENTRICITY/%3E0.25/OBJECT_TYPE/payload/orderby/NORAD_CAT_ID,EPOCH/format/3le
# https://www.space-track.org/basicspacedata/query/class/gp/EPOCH/%3Enow-30/MEAN_MOTION/%3E11.25/ECCENTRICITY/%3C0.25/OBJECT_TYPE/payload/orderby/NORAD_CAT_ID,EPOCH/format/3le
tle => {
ECCENTRICITY => '<0.25',
EPOCH => '>now-30',
MEAN_MOTION => '>11.25',
OBJECT_TYPE => 'payload',
},
},
highly_elliptical_orbit => { # HEO
name => 'Highly Elliptical Orbit',
# As of 2026-01-19
# https://www.space-track.org/basicspacedata/query/class/gp/EPOCH/%3Enow-30/ECCENTRICITY/%3E0.25/OBJECT_TYPE/payload/orderby/NORAD_CAT_ID,EPOCH/format/3le
tle => {
ECCENTRICITY => '>0.25',
EPOCH => '>now-30',
OBJECT_TYPE => 'payload',
},
},
lib/Astro/SpaceTrack.pm view on Meta::CPAN
},
well_tracked_objects => {
name => 'Well-Tracked Objects',
# As of 2026-01-19
# https://www.space-track.org/basicspacedata/query/class/gp/EPOCH/%3Enow-30/NORAD_CAT_ID/80000--89999/orderby/NORAD_CAT_ID/format/tle/emptyresult/show
# satcat => {
# COUNTRY => 'UNKN',
# SITE => 'UNKN',
# },
tle => {
EPOCH => '>now-30',
NORAD_CAT_ID => '80000--89999',
format => 'tle',
epmtyresult => 'show',
},
},
# Favorites (whatever that means). As of 2026-01-19 these
# are specific to the individual user, and therefore
# useless.
navigation => {
name => 'Navigation satellites',
favorite => 'Navigation',
tle => {
EPOCH => '>now-30',
},
# number => 5,
},
weather => {
name => 'Weather satellites',
favorite => 'Weather',
tle => {
EPOCH => '>now-30',
},
# number => 7,
},
amateur => {
favorite => 'Amateur',
name => 'Amateur Radio satellites',
tle => {
EPOCH => '>now-30',
},
# number => 19,
},
visible => {
favorite => 'Visible',
name => 'Visible satellites',
tle => {
EPOCH => '>now-30',
},
# number => 21,
},
special => {
favorite => 'Special_interest',
name => 'Special interest satellites',
tle => {
EPOCH => '>now-30',
},
# number => 23,
},
bright_geosynchronous => {
favorite => 'brightgeo',
name => 'Bright Geosynchronous satellites',
tle => {
EPOCH => '>now-30',
},
},
human_spaceflight => {
favorite => 'human_spaceflight',
name => 'Human Spaceflight',
tle => {
EPOCH => '>now-30',
},
},
# Added by TRW
payloads => {
name => 'All payloads',
# satcat => {
# OBJECT_TYPE => 'PAYLOAD',
# },
tle => {
EPOCH => '>now-30',
OBJECT_TYPE => 'payload',
},
},
},
],
);
my %mutator = ( # Mutators for the various attributes.
addendum => \&_mutate_attrib, # Addendum to banner text.
banner => \&_mutate_attrib,
cookie_expires => \&_mutate_spacetrack_interface,
cookie_name => \&_mutate_spacetrack_interface,
domain_space_track => \&_mutate_spacetrack_interface,
dump_headers => \&_mutate_dump_headers, # Dump all HTTP headers. Undocumented and unsupported.
fallback => \&_mutate_attrib,
filter => \&_mutate_attrib,
identity => \&_mutate_identity,
iridium_status_format => \&_mutate_iridium_status_format,
max_range => \&_mutate_number,
password => \&_mutate_authen,
pretty => \&_mutate_attrib,
prompt => \&_mutate_attrib,
scheme_space_track => \&_mutate_attrib,
session_cookie => \&_mutate_spacetrack_interface,
space_track_version => \&_mutate_space_track_version,
url_iridium_status_kelso => \&_mutate_attrib,
url_iridium_status_mccants => \&_mutate_attrib,
url_iridium_status_sladen => \&_mutate_attrib,
username => \&_mutate_authen,
verbose => \&_mutate_attrib,
verify_hostname => \&_mutate_verify_hostname,
webcmd => \&_mutate_attrib,
with_name => \&_mutate_attrib,
);
my %accessor = (
cookie_expires => \&_access_spacetrack_interface,
cookie_name => \&_access_spacetrack_interface,
domain_space_track => \&_access_spacetrack_interface,
session_cookie => \&_access_spacetrack_interface,
lib/Astro/SpaceTrack.pm view on Meta::CPAN
}
sub _get_readline { ## no critic (Subroutines::RequireArgUnpacking)
my ( $self ) = @_;
require Term::ReadLine;
$rdln ||= Term::ReadLine->new (
'SpaceTrack orbital element access');
@_ > 1
and $_[1] = ( $rdln->OUT || \*STDOUT ); # $stdout
if ( 'Term::ReadLine::Perl' eq $rdln->ReadLine() ) {
require File::Glob;
$readline_word_break_re ||= qr<
[\Q$readline::rl_completer_word_break_characters\E]+
>smx;
no warnings qw{ once };
$readline::rl_completion_function = sub {
my ( $text, $line, $start ) = @_;
return $self->__readline_completer(
$text, $line, $start );
};
}
return sub { $rdln->readline ( $self->getv( 'prompt' ) ) };
}
=for html <a name="source"></a>
=item $st->source ($filename);
This convenience method reads the given file, and passes the individual
lines to the shell method. It croaks if the file is not provided or
cannot be read.
=cut
# We really just delegate to _source, which unpacks.
sub source {
my $self = _instance( $_[0], __PACKAGE__ ) ? shift :
Astro::SpaceTrack->new ();
$self->shell ($self->_source (@_), 'exit');
return;
}
=for html <a name="spacetrack"></a>
=item $resp = $st->spacetrack ($name);
This method returns predefined sets of data from the Space Track web
site, using either canned queries or global favorites.
The following catalogs are available:
Name Description
full Full catalog
payloads All payloads
* navigation Navigation satellites
* weather Weather satellites
geosynchronous Geosynchronous bodies
iridium Iridium satellites
orbcomm OrbComm satellites
globalstar Globalstar satellites
intelsat Intelsat satellites
inmarsat Inmarsat satellites
* amateur Amateur Radio satellites
* visible Visible satellites
* special Special satellites
* bright_geosynchronous
Bright Geosynchronous satellites
* human_spaceflight
Human Spaceflight
well_tracked_objects
Well-Tracked Objects not associated
with a specific launch
The starred items are 404 as of 2026-01-19. They are deprecated and will
be removed.
The following option is supported:
-json
specifies the TLE be returned in JSON format
Options may be specified either in command-line style
(that is, as C<< spacetrack( '-json', ... ) >>) or as a hash reference
(that is, as C<< spacetrack( { json => 1 }, ... ) >>).
This method returns an L<HTTP::Response|HTTP::Response> object. If the
operation succeeded, the content of the response will be the requested
data, unzipped if you used the version 1 interface.
If you requested a non-existent catalog, the response code will be
C<HTTP_NOT_FOUND> (a.k.a. 404); otherwise the response code will be
whatever the underlying HTTPS request returned.
A Space Track username and password are required to use this method.
If this method succeeds, the response will contain headers
Pragma: spacetrack-type = orbit
Pragma: spacetrack-source = spacetrack
These can be accessed by C<< $st->content_type( $resp ) >> and
C<< $st->content_source( $resp ) >> respectively.
A list of valid names and brief descriptions can be obtained by calling
C<< $st->names ('spacetrack') >>.
If you have set the C<verbose> attribute true (e.g. C<< $st->set
(verbose => 1) >>), the content of the error response will include the
list of valid names. Note, however, that under version 1 of the
interface this list does not determine what can be retrieved.
This method implicitly calls the C<login()> method if the session cookie
is missing or expired. If C<login()> fails, you will get the
HTTP::Response from C<login()>.
=cut
{
my %unpack_query = (
ARRAY_REF() => sub { return @{ $_[0] } },
HASH_REF() => sub { return $_[0] },
);
# Unpack a Space Track REST query. References are unpacked per the
# above table, if found there. Undefined values return an empty hash
# reference. Anything else croaks with a stack trace.
lib/Astro/SpaceTrack.pm view on Meta::CPAN
}
return;
}
} # End local symbol block.
# $self->_deprecation_notice( $method, $argument );
#
# This method centralizes deprecation. Deprecation is driven of
# the %deprecate hash. Values are:
# false - no warning
# 1 - warn on first use
# 2 - warn on each use
# 3 - die on each use.
{
use constant _MASTER_IRIDIUM_DEPRECATION_LEVEL => 3;
use constant _MASTER_FAVORITE_DEPRECATION_LEVEL => 2;
my %deprecate = (
celestrak => {
# sts => 3,
# '--descending' => 3,
# '--end_epoch' => 3,
# '--last5' => 3,
# '--sort' => 3,
# '--start_epoch' => 3,
},
amsat => 1,
attribute => {
# direct => 3,
url_iridium_status_kelso => _MASTER_IRIDIUM_DEPRECATION_LEVEL,
url_iridium_status_mccants => _MASTER_IRIDIUM_DEPRECATION_LEVEL,
url_iridium_status_sladen => _MASTER_IRIDIUM_DEPRECATION_LEVEL,
iridium_status_format => 1,
},
iridium_status => _MASTER_IRIDIUM_DEPRECATION_LEVEL,
iridium_status_format => {
kelso => 3,
mccants => 3,
sladen => _MASTER_IRIDIUM_DEPRECATION_LEVEL,
},
option => {
last5 => 2,
},
mccants => {
mcnames => 3,
quicksat => 3,
vsnames => 3,
},
BODY_STATUS_IS_OPERATIONAL => _MASTER_IRIDIUM_DEPRECATION_LEVEL,
BODY_STATUS_IS_SPARE => _MASTER_IRIDIUM_DEPRECATION_LEVEL,
BODY_STATUS_IS_TUMBLING => _MASTER_IRIDIUM_DEPRECATION_LEVEL,
BODY_STATUS_IS_DECAYED => _MASTER_IRIDIUM_DEPRECATION_LEVEL,
spacetrack => {
navigation => _MASTER_FAVORITE_DEPRECATION_LEVEL,
weather => _MASTER_FAVORITE_DEPRECATION_LEVEL,
amateur => _MASTER_FAVORITE_DEPRECATION_LEVEL,
visible => _MASTER_FAVORITE_DEPRECATION_LEVEL,
special => _MASTER_FAVORITE_DEPRECATION_LEVEL,
bright_geosynchronous => _MASTER_FAVORITE_DEPRECATION_LEVEL,
human_spaceflight => _MASTER_FAVORITE_DEPRECATION_LEVEL,
},
);
sub _deprecation_notice {
my ( undef, $method, $argument ) = @_; # Invocant unused
defined $method
or ( $method = ( caller 1 )[3] ) =~ s/ .* :: //smx;
my $level = $deprecate{$method}
or return;
my $desc = $method;
if ( ref $level ) {
defined $argument or Carp::confess( 'Bug - $argument undefined' );
$level = $level->{$argument}
or return;
$desc = "$method $argument";
}
$level >= 3
and Carp::croak "$desc is retracted";
warnings::enabled( 'deprecated' )
and Carp::carp "$desc is deprecated";
1 == $level
or return;
if ( ref $deprecate{$method} ) {
$deprecate{$method}{$argument} = 0;
} else {
$deprecate{$method} = 0;
}
return;
}
}
# _dump_cookie is intended to be called from inside the
# HTTP::Cookie->scan method. The first argument is prefix text
# for the dump, and the subsequent arguments are the arguments
# passed to the scan method.
# It dumps the contents of the cookie to STDERR via a warn ().
# A typical session cookie looks like this:
# version => 0
# key => 'spacetrack_session'
# val => whatever
# path => '/'
# domain => 'www.space-track.org'
# port => undef
# path_spec => 1
# secure => undef
# expires => undef
# discard => 1
# hash => {}
# The response to the login, though, has an actual expiration
# time, which we take cognisance of.
{ # begin local symbol block
my @names = qw{version key val path domain port path_spec secure
expires discard hash};
sub _dump_cookie {
my ( $self, $prefix, @args ) = @_;
( run in 1.173 second using v1.01-cache-2.11-cpan-39bf76dae61 )