
    R1iX                        d dl mZ d dlZd dlZd dlZd dlZd dlmZ d dlmZ d dl	m	Z	 d dl
Z
d dlZddlmZ ddlmZ dd	lmZ dd
lmZmZmZmZ ddlmZ ddlmZ ddlmZ 	 d dlmZ ejB                  dk\  rejD                  Z#nejH                  Z#	 d dl%m&Z& 	 d dl(m)Z) d dl*m+Z+ 	  e+dd       ej`                  jb                  jd                  dk(  Z3d Z4dZ5dZ6dZ7dZ8dZ9d Z: G d  d!e;      Z<d" Z=d# Z>d$ Z?d*d%Z@d+d&ZAd' ZB G d( d)e;      ZCy#  d dl m Z Y xY w# e'$ r dZ&Y w xY w#  d dl)m)Z) d dl,m+Z+ Y xY w# e-$ r dZ.Y e/$ r dZ.Y w xY w),    )print_functionN)fnmatch)get_data)time   )iers)Splines)load_bundled_npy)_build_legacy_dataparse_deltat_dataparse_deltat_predsparse_leap_seconds)SpiceKernel)EarthSatellite)	Timescale)BytesIO)StringIO)   r   )create_default_context)urlparse)urlopen cafileFTPseudoOutputFilec                 P    t        |       j                  j                  d      d   S )z(Return the last path component of a url./)r   pathsplit)urls    R/home/cursorai/projects/iching/venv/lib/python3.12/site-packages/skyfield/iokit.py_filename_ofr#   :   s"    C=##C(,,    z&https://hpiers.obspm.fr/iers/bul/bulc/z/ftp://ftp.iers.org/products/eop/rapid/standard/z-https://ssd.jpl.nasa.gov/ftp/eph/planets/bsp/z3https://naif.jpl.nasa.gov/pub/naif/generic_kernels/zBhttps://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/satellites/c                     t        | d      S )Nrb)mode)open)r   s    r"   _open_binaryr)   D   s    4  r$   c                       e Zd ZdZddZd Zd Zd ZddZd Z	d Z
d	 ZddZ	 	 ddZddZddZddZed        Zy
)LoaderaX  A tool for downloading and opening astronomical data files.

    A default `Loader` that saves data files to the current working
    directory can be imported directly from the Skyfield API::

        from skyfield.api import load

    But users can also create a `Loader` of their own, if there is
    another directory they want data files saved to, or if they want to
    specify different options.  The directory is created automatically
    if it does not yet exist::

        from skyfield.api import Loader
        load = Loader('~/skyfield-data')

    The options are:

    ``verbose``
      If set to ``False``, then the loader will not print a progress bar
      to the screen each time it downloads a file.  (If the standard
      output is not a TTY, then no progress bar is printed anyway.)

    ``expire``
      (This option is no longer supported.)

    Once a `Loader` is created, it can be called like a function to
    open, or else to download and open, a file whose name it recognizes::

        planets = load('de405.bsp')

    Each loader also supports an attribute and a few methods.

    c                 R   t         j                  j                  |      | _        || _        g | _        	 t        j                  | j                         t        t        t        dz   t        dz   t        dz   dt        fdt        fgd| _        t"        t$        t&        d| _        dt*        fgdt,        fgdt,        fgdt,        fgd	| _        y # t        $ rQ}|j                  t        j                  k7  r*t         j                  j                  | j                        s Y d }~d }~ww xY w)
Nzfk/satellites/zpck/zpck/a_old_versions/zjup*.bspz*.bsp)finals2000A.allLeap_Second.datzmoon_080317.tfzmoon_pa_de421_1900-2050.bpczpck00008.tpc.bsp)deltat.datadeltat.predsr.   *)r/   z.bpcz.tpcz.tf)osr   
expanduser	directoryverboseeventsmakedirsOSErrorerrnoEEXISTisdir_IERS2_IERS_NAIF_KERNELS_NAIF_JPLurlsr   r   r   parsersr   r)   openers)selfr5   r6   expirees        r"   __init__zLoader.__init__i   s   ++I6	KK'  &$+.>>+86+A),AAU#$

	 -.1
 +& <()<(),'(
1  	ww%,,&rww}}T^^/L	s   C 	D&AD!!D&c                 x    | j                   dk(  r|S t        j                  j                  | j                   |      S )z;Return the path to ``filename`` in this loader's directory..)r5   r3   r   joinrE   filenames     r"   path_tozLoader.path_to   s,    >>S Oww||DNNH55r$   c                     t        j                  | j                  |            j                  }t	               |z
  }|dz  S )z@Return how recently ``filename`` was modified, measured in days.g     @)r3   statrN   st_mtimer   )rE   rM   mtimesecondss       r"   days_oldzLoader.days_old   s5    X./88&5.  r$   c                 ^    t         j                  j                  | j                  |            S N)r3   r   existsrN   rL   s     r"   _existszLoader._exists   s    ww~~dll8455r$   c                    d|v r*|}t        |      j                  j                  d      d   }nt        | j                  |      }|r||z  }t        | j
                  |      }t        | j                  |      }||t        dj                  |            |r:| j                  d||j                         t        t        d|            } ||      S | j                  ||||      }	|:| j                  d|j                         t        |	d	      5 } ||      cddd       S | j                  d
|j                          ||	      S # 1 sw Y   yxY w)z7Open the given file, downloading it first if necessary.://r   r   Nz5Skyfield does not know how to open a file named {0!r}z%{0}
  Parsing builtin file with {1}()zskyfield.dataz  Parsing with {0}()r&   z  Opening with {0})r   r   r    _searchrB   rC   rD   
ValueErrorformat_log__name__r   r   _assurer(   )
rE   rM   reloadbackupbuiltinr!   parseropenerfr   s
             r"   __call__zLoader.__call__   s9   HC}))//4R8H $))X.Cxx0x0N ,,2F8,<> > II>1(;<A!9||C66:II,foo>dD!Qay "! II*FOO<$<	 "!s   EEc                 D   | j                  |      }t        j                  j                  |      }| j	                  |       |r| j	                  d       |r|rG|t        dj                  |            | j	                  d|       t        ||| j                  |       |S )Nz  File already existsz-Skyfield does not know where to download {!r}z  Downloading {0}rb   )	rN   r3   r   rW   r^   r\   r]   downloadr6   )rE   r!   rM   ra   rb   r   rW   s          r"   r`   zLoader._assure   s    ||H%%		$II-.6{ !P"(&"24 4II)3/S$V<r$   c                 T    | j                   j                   |j                  |        y rV   )r7   appendr]   )rE   messageargss      r"   r^   zLoader._log   s    >7>>401r$   c                 p    t        | j                  |      }|r||z   S t        dj                  |            )zReturn the URL Skyfield will try downloading for a given filename.

        Raises ``ValueError`` if Skyfield doesn't know where to get the
        file based on its name.

        z&Skyfield doesn't know the URL of {0!r})r[   rB   r\   r]   )rE   rM   bases      r"   	build_urlzLoader.build_url   s;     tyy(+(?"A &*, 	,r$   Nc                     i }| j                  |||      5 }t        |      D ]*  \  }}|||j                  j                  <   |D ]  }|||<   	 , 	 ddd       |S # 1 sw Y   |S xY w)a  Load and parse a satellite TLE file.

        DEPRECATED: in a misguided attempt to be overly convenient, this
        routine builds an unweildy dictionary of satellites with keys of
        two different Python types: integer keys for satellite numbers,
        and string keys for satellite names. It even lists satellites
        like ``ISS (ZARYA)`` twice, in case the user wants to look them
        up by a single name like ``ZARYA``.  What a mess.  Users should
        instead call the simple ``tle_file()`` method, and themselves
        build any dictionaries they need.

        See the :meth:`~skyfield.iokit.Loader.open()` documentation for
        the meaning of the ``reload`` and ``filename`` parameters.

        ra   rM   N)r(   	parse_tlemodelsatnum)	rE   r!   ra   rM   drf   namessatnames	            r"   tlez
Loader.tle   so      YYs6HY='l
s&)#))""#!D!AdG " + >
  >
 s   9AA%c                     | j                  |||      5 }t        t        |||            cddd       S # 1 sw Y   yxY w)u?  Load and parse a TLE file, returning a list of Earth satellites.

        Given a URL or local path to an ASCII text file, this loads a
        series of TLE “Two-Line Element” sets and returns a list of
        :class:`~skyfield.sgp4lib.EarthSatellite` objects for them.
        See :doc:`earth-satellites`.

        See the :meth:`~skyfield.iokit.Loader.open()` method for the
        meaning of the ``reload`` and ``filename`` parameters.

        See the :meth:`parse_tle_file()` function for the meaning of the
        ``ts`` and ``skip_names`` parameters.

        rs   N)r(   listparse_tle_file)rE   r!   ra   rM   ts
skip_namesrf   s          r"   tle_filezLoader.tle_file  s5      YYs6HY=q"j9: >==s   5>c                     d|vr| j                  |      }|'t        |      j                  j                  d      d   }| j	                  |      }t        ||| j                  |       |S )u  Download a file, even if it’s already on disk; return its path.

        You can specify the local ``filename`` to which the file will be
        saved; the default is to use the final component of ``url``.
        Set ``backup`` to ``True`` if you want an already-existing file
        moved out of the way instead of overwritten.

        Your operating system may raise any of several errors during a
        download: hostname lookup failure (this is the usual symptom if
        you are disconnected from the Internet); the server refusing the
        connection; and the connection closing mid-download.  Skyfield
        makes no attempt to intercept or interpret these errors — which
        vary by operating system — so your application itself should
        catch network errors if it needs to avoid printing raw Python
        exceptions, or if you want to retry failed downloads.

        rZ   r   r   ri   )rq   r   r   r    rN   rj   r6   )rE   r!   rM   rb   r   s        r"   rj   zLoader.download  sd    $ ..%C}))//4R8H||H%dDLL8r$   c                    d|vr8|}t         j                  j                  | j                  |      }t	        ||      S |'t        |      j                  j                  d      d   }| j                  ||||      }t	        ||      S )a,  Open a file, downloading it first if it does not yet exist.

        Unlike when you call a loader directly like ``my_loader()``,
        this ``my_loader.open()`` method does not attempt to parse or
        interpret the file; it simply returns an open file object.

        The ``url`` can be either an external URL, or else the path to a
        file on the current filesystem.  A relative path will be assumed
        to be relative to the base directory of this loader object.

        If a URL was provided and the ``reload`` parameter is true, then
        any existing file will be removed before the download starts.

        The ``filename`` parameter lets you specify an alternative local
        filename instead of having the filename extracted from the final
        component of the URL.

        rZ   r   r   )r3   r   rK   r5   r(   r   r    r`   )rE   r!   r'   ra   rM   rb   path_that_might_be_relativer   s           r"   r(   zLoader.open.  s~    & *-'77<<0KLDd##}))//4R8H||C66:D$r$   c                 l   | j                   }|rWt        d      }|d   }|t        j                  t	        |            z  }|d   dz  j                  d      }||f}|d   }|d   }	n |d      r= |d	      r5 |d
      r- | d      }
 | d	      } | d
      \  }}t        |
||      \  }}}	nb| j                  d      }| j                  |      5 }t        j                  |      \  }}ddd       t        j                        \  }}}}	||f}|t        dd|g      }t        |||	      S # 1 sw Y   ExY w)u(  Return a `Timescale` built using official Earth rotation data.

        ``delta_t`` — Lets you override the standard ∆T tables by
        providing your own ∆T offset in seconds.  For details, see
        :ref:`custom-delta-t`.

        ``builtin`` — By default, Skyfield uses ∆T and leap second
        tables that it carries internally; to instead load this data
        from files, set this option to ``False``.  For compatibility
        with Skyfield ≤ 1.30, if you have on disk the three files
        ``deltat.data``, ``deltat.preds``, and ``Leap_Second.dat``, then
        Skyfield will load them.  Otherwise, Skyfield will download and
        use ``finals2000A.all`` from the International Earth Rotation
        Service.  For details, see :ref:`downloading-timescale-files`.

        ziers.npztt_jd_minus_arangedelta_t_1e7g    cA   
leap_datesleap_offsetsr0   r1   r.   r-   Nr   r   )rX   r
   nparangelenroundr   rq   r(   r   parse_dut1_from_finals_allbuild_timescale_arraysr	   r   )rE   delta_trc   rG   arraysdaily_ttdaily_delta_tdelta_t_recentr   r   deltat_datadeltat_preds_leap_second_datr!   rf   utc_mjddut1s                     r"   	timescalezLoader.timescaleL  sV   " LL%j1F23H		#h-00H#M2S8??BM%}4N-J!.1L}!N"3:K8L
 }-K/L!%&7!8A7I\?8<4NJ ..!23C31 $ ? ? B   ++GT: >HmZ%}4N$aG_5N\BB  s   D**D3c                 8    dj                  | j                        S )N
)rK   r7   )rE   s    r"   logz
Loader.log~  s    yy%%r$   )TF)FFF)FN)FNNFNF)r&   FNF)NT)r_   
__module____qualname____doc__rH   rN   rT   rX   rg   r`   r^   rq   r{   r   rj   r(   r   propertyr    r$   r"   r+   r+   G   si     B*
X6!6% N2,0 48%*;&4 <0Cd & &r$   r+   c                     | j                  |      }||S t        j                  j                  |      \  }}| j                  |      }||D ]  \  }}t	        ||      s|c S  y)z.Search a Loader data structure for a filename.N)getr3   r   splitextr   )mappingrM   resultrz   extpatternresult2s          r"   r[   r[     sj    [["F  *ID#[[F &GWx) !' r$   c                     t         j                  j                  |       } t         j                  j                  |       \  }}|dk(  rt	        |       S t        dj                  |             )a8  Open a file on your local drive, using its extension to guess its type.

    This routine only works on ``.bsp`` ephemeris files right now, but
    will gain support for additional file types in the future. ::

        from skyfield.api import load_file
        planets = load_file('~/Downloads/de421.bsp')

    r/   zunrecognized file extension: {})r3   r   r4   r   r   r\   r]   )r   rp   r   s      r"   	load_filer     sY     77d#D  &ID#
f}4  
6==dC
DDr$   c              #     K   dx}}| D ]G  }|j                  d      r.t        |      dk\  r|j                  d      rt        |      dk\  r|j                  d      }t        |      dk(  r#|j                  d      j                         }|g}n;|j                  d      r&|d	d
 j                  d      j                         }|g}nd
}d}|j                  d      }|j                  d      }t	        |||      }|rKd|v rG|j                  d      \  }	}
|
j                  d      }
|j                  |	       |j                  |
       ||f |}|}J y
w)a?  Parse a file of TLE satellite element sets.

    DEPRECATED: this routine is overly complicated, doing extra work to
    try to guess several ways in which the user might want to look up
    satellites by name.  Use ``parse_tle_file()`` instead.

    TODO: convert this into a wrapper around ``parse_tle_file()``.

    r$      1 E      2 s   
   ascii   0    Nr   z ())
startswithr   rstripdecoder   r    rl   )fileobjb0b1b2rz   rx   line1line2ry   
short_namesecondary_names              r"   rt   rt     s<     MBMM% SW]MM% SW]7#B2w"}yy)002u%!"v}}W-446IIg&EIIg&E t4C .2ZZ-=*
N!/!6!6s!;Z(^,*? s   EEc              #     K   dx}}| D ]  }|j                  d      rt        |      dk\  r|j                  d      rt        |      dk\  rv|s;|r9|j                  d      }|j                  d      r|dd }|j                  d	      }nd}|j                  d	      }|j                  d	      }t	        ||||       dx}}|}|} yw)
u  Parse lines of TLE satellite data, yielding a sequence of satellites.

    Given a sequence ``lines`` of byte strings (which can be an open
    binary file, which acts like a sequence of lines in Python), this
    routine yields an :class:`~skyfield.sgp4lib.EarthSatellite` for each
    pair of adjacent lines that start with ``"1 "`` and ``"2 "`` and
    have 69 or more characters each.  If the line preceding a TLE is not
    part of another TLE, it is used as the satellite’s ``.name``.

    If you pass a ``ts`` timescale, Skyfield will use it to build the
    ``.epoch`` date attribute on each satellite; otherwise a timescale
    derived from Skyfield’s built-in leap second files will be used.

    If for a particular file you see random lines of text being
    interpreted as satellite names, set ``skip_names`` to ``True`` and
    Skyfield will not try to store satellite names.

    See :doc:`earth-satellites` for details.  An exception is raised if
    the attempt to parse a pair of candidate lines as TLE lines fails.

    r$   r   r   r   s    
r   r   Nr   )r   r   r   r   r   )	linesr   r   r   r   r   rz   r   r   s	            r"   r~   r~     s     , MBMM% SW]MM% SW]"YYx(=='ABByy)IIg&EIIg&E tR88MBBB' s   CCc                    	 t         ,t        t        j                               }t        | |      }n1t        r t        | t        j                               }nt        |       }|t        j                  j                         }d}	|r~t        rHt        dj                  t        j                  j!                  |            t        j                         n0t#        |      }	t%        |j&                  j)                  dd            }
|d	z   x}}t+        t        d
d      t        j,                  z  t        j.                  z  t        j0                  z  }d}	 	 t        j2                  ||d      }	 t        j:                  |d      5 }	 d}	 |j=                  |      }|sn4|j?                  |       |tA        |      z  }|	|	jC                  |
       H|jE                          	 ddd       t        j                  jG                  |      r|rtI        |       	 tK        ||       y# t
        $ r)}t        dj                  | |            }d|_        |d}~ww xY w# t4        $ r?}|j6                  t6        j8                  k7  r |dz  }dj                  ||      }Y d}~nd}~ww xY wQ# t
        $ r }t        dj                  | |            d}~ww xY w# 1 sw Y   xY w# t
        $ r!}t        dj                  |||            d}~ww xY w)a  Download a file from a URL, possibly displaying a progress bar.

    Saves the output to the file named by `path`.  If the URL cannot be
    downloaded or the file cannot be written, an ``IOError`` is raised.

    Normally, if the standard error output is a terminal, then a
    progress bar is displayed to keep the user entertained.  Specify
    `verbose=True` or `verbose=False` to override this behavior.

    Nr   )contextzcannot download {0} because {1}zDownloading {0} ...)filezcontent-lengthr   z	.downloadO_BINARYr   r   i  z{0}{1}wbzerror getting {0} - {1}zerror renaming {0} to {1} - {2})&r   certifiwherer   _supports_cafile_argument	ExceptionIOErrorr]   	__cause__sysstderrisatty_running_IDLEprintr3   r   basenameProgressBarintheadersr   getattrO_CREATO_EXCLO_RDWRr(   r9   r:   r;   fdopenreadwriter   reportflushrW   _rename_original_replace)r!   r   r6   	blocksizerb   ssl_context
connectionrG   e2barcontent_lengthtempbasetempnameflagsifdwlengthdatas                      r"   rj   rj     s   !-0HK k:J& W]]_=J J **##%
C'..rww/?/?/EFzz# d#C !3!3!7!78H"!MNN ,,HxB
A&3bii?"))KE	A
	5%0B  
2t		DF!y1#d)#?JJv~6  GGI 
" 
ww~~d 4 u  6==c1EF2  	4ww%,,&FAx3H		4 2  	D3::3BCC	D 
	0   7>>dA   	  ss   A#H$ I KAJ&K $	I-$II	J!"5JJ!&	K/K

KKK	L'LLc                     t        j                  d      D ]K  }| j                  dd      \  }}dj                  |||      }t        j
                  j                  |      rK n t	        j                  |        y )Nr   rJ   z{0}.old{1}.{2})	itertoolscountrsplitr]   r3   r   rW   rename)r   nprefixsuffixbackup_paths        r"   r   r   I  s`    __QS!,&--fa@ww~~k*	  
 IIdK r$   c                       e Zd Zd Zd Zy)r   c                 Z    t         j                  j                  |      | _        d| _        y )Nr   )r3   r   r   rM   t0)rE   r   s     r"   rH   zProgressBar.__init__R  s    ((.r$   c                 F   |dk  ry d|z  |z  }|dk7  rt               | j                  z
  dk  ry t               | _        d|dz  z  }t        dj                  ||| j                        |dk(  rdndt
        j                  	       t
        j                  j                          y )
Nr   d   g      ?#r   z[{0:33}] {1:3}% {2}r   r   )endr   )r   r   r   r]   rM   r   r   r   )rE   bytes_so_farbytes_totalpercentr   s        r"   r   zProgressBar.reportV  s    ?$3sN$''!1C!7&W\"%,,S'4==I"c>$	E

r$   N)r_   r   r   rH   r   r   r$   r"   r   r   Q  s    
r$   r   r   )Ni   F)D
__future__r   r   r3   r:   r   r   pkgutilr   r   r   numpyr   r   r   curvelibr	   	functionsr
   io_timescaler   r   r   r   jpllibr   sgp4libr   timelibr   ior   r   version_inforeplacer   r   sslr   ImportErrorurllib.parser   urllib.requestr   urllib2	TypeErrorr   r\   r   	__class__r_   r   r#   r>   r=   rA   r?   r@   r)   objectr+   r[   r   rt   r~   rj   r   r   r   r$   r"   <module>r     s^   %  	  
        '    # - vzzHyyH"* %&
%Bt %%..2DD- 	1	:6EL!y&V y&v	E *X*XP d!& m-,  "!" !  & % % $%sB   "D D D' %
D: DD$#D$'D7:EEE