U
    kuf!                  
   @  s  d Z ddlmZ ddlZddlZddlZddlmZmZ ddlm	Z	 ddl
mZ ddlmZmZ ddlmZ d	d
lmZ d	dlmZmZ d	dlmZ ee	ddee	ddee	ddee	ddee	ddee	ddiZee	dddZee	ddZdD ],Zee	ddeZee	deZeee< qdddgZej Z!e!dde!dde!dd e!d!de!d"diZ"d#d$d%d&Z#d#d#d'd(d)d*Z$d=d+d+d,d'd-d.d/Z%d#d#d'd(d0d1Z&d#d#d'd(d2d3Z'd#d,d4d5d6d7Z(d'd$d8d9Z)G d:d; d;eZ*e*j+Z,e-d<kre,  dS )>a  Migrating IPython < 4.0 to Jupyter

This *copies* configuration and resources to their new locations in Jupyter

Migrations:

- .ipython/
  - nbextensions -> JUPYTER_DATA_DIR/nbextensions
  - kernels ->  JUPYTER_DATA_DIR/kernels

- .ipython/profile_default/
  - static/custom -> .jupyter/custom
  - nbconfig -> .jupyter/nbconfig
  - security/

    - notebook_secret, notebook_cookie_secret, nbsignatures.db -> JUPYTER_DATA_DIR

  - ipython_{notebook,nbconvert,qtconsole}_config.py -> .jupyter/jupyter_{name}_config.py


    )annotationsN)datetimetimezone)Path)Any)JSONFileConfigLoaderPyFileConfigLoader)
get_logger   )
JupyterApp)jupyter_config_dirjupyter_data_dir)ensure_dir_existsz{ipython_dir}Znbextensionsz{jupyter_data}Zkernelsz	{profile}Znbconfigz{jupyter_config}ZstaticZcustom)Znotebook_secretZnotebook_cookie_secretznbsignatures.dbsecurityZnotebookZ	nbconvertZ	qtconsolez\bIPythonQtConsoleApp\bZJupyterQtConsoleAppz\bIPythonWidget\bZJupyterWidgetz\bRichIPythonWidget\bZRichJupyterWidgetz\bIPython\.html\bz\bIPython\.nbconvert\bstrreturnc                   C  s   t jdttd S )a  Return the IPython directory location.

    Not imported from IPython because the IPython implementation
    ensures that a writable directory exists,
    creating a temporary directory if not.
    We don't want to trigger that when checking if migration should happen.

    We only need to support the IPython < 4 behavior for migration,
    so importing for forward-compatibility and edge cases is not important.
    Z
IPYTHONDIRz
~/.ipython)osenvirongetr   r   
expanduser r   r   8/tmp/pip-unpacked-wheel-a5h937xx/jupyter_core/migrate.pyget_ipython_dirH   s    r   bool)srcdstr   c                 C  s   t  }t| s |d|  dS t| rRt|rF|d| dS t|  |d| | tt|j	 t
j| |dd dS )z#Migrate a directory from src to dstzNo files in %sF%s already existsCopying %s -> %sT)symlinks)r	   r   listdirdebugr   existsrmdirinfor   parentshutilcopytreer   r   logr   r   r   migrate_dirV   s    

r*   z
str | Pathr   )r   r   substitutionsr   c              	   C  s   t  }t| r"|d| dS |d| | tt|j t| | |rtj	t|dd}|
 }W 5 Q R X | D ]\}}|||}q|tj	t|ddd}|| W 5 Q R X dS )zMigrate a single file from src to dst

    substitutions is an optional dict of {regex: replacement} for performing replacements on the file.
    r   Fr   utf-8encodingwT)r	   r   r"   r!   r$   r   r%   r&   copyopenreaditemssubwrite)r   r   r+   r)   ftextpatreplacementr   r   r   migrate_fileh   s    r:   c                 C  sB   t  }t|  rt| |S t|  r2t| |S |d|  dS )z:Migrate one item

    dispatches to migrate_dir/_file
    zNothing to migrate for %sF)r	   r   is_filer:   is_dirr*   r!   r(   r   r   r   migrate_one   s    

r=   c              	   C  sN  t  }d}t| d}t| d}d}t| rtj|dd>}|  }| D ]"}	|	 sR|	 dsRd} qvqRW 5 Q R X d}
t| rtj|dd&}|  }|do|	d	}
W 5 Q R X |r|
d
| |
r|
d
| |r|
rdS t| |r
|
st| |s.t|t|dr.d}|
sJt|t|drJd}|S )zvMigrate non-empty custom.js,css from src to dst

    src, dst are 'custom' directories containing custom.{js,css}
    Fz	custom.jsz
custom.cssTr,   r-   )/**z//r>   z*/zIgnoring empty %s)r	   r   r;   r1   r2   strip
splitlinesisspace
startswithendswithr!   r   r:   )r   r   r)   migratedZ	custom_jsZ
custom_cssZcustom_js_emptyr6   ZjslineZcustom_css_emptycssr   r   r   migrate_static_custom   s>    

rH   z	list[Any])nameenvr   c                 C  s   t  }tt|d  d|  d}tt|d  d|  d}ttd}g }dD ]Z}|| }|| }	t| rP|| | }
|
rt||	tdr|	| qP|
d| qP|S )	zWMigrate a config file.

    Includes substitutions for updated configurable names.
    profileZipython__configjupyter_configZjupyter_)z.pyz.json)r+   z#Not migrating empty config file: %s)r	   r   r   r   r   r"   Zload_configr:   config_substitutionsappendr!   )rI   rJ   r)   Zsrc_baseZdst_baseloadersrE   extr   r   cfgr   r   r   migrate_config   s"    rS   c            
   	   C  s   t  t t ttt dd} d}t D ]:\}}|jf | }|jf | }t| r,t	||r,d}q,t
D ]}t|| rld}qltjf | }tjf | }t| rt||rd}t| d  tjt| d dddd	}	|	tjtjd
  W 5 Q R X |S )z(Migrate IPython configuration to JupyterZprofile_default)Zjupyter_datarM   Zipython_dirrK   FTrM   rE   r/   r,   r-   )tz)r   r   r   r   r   
migrationsr3   formatr"   r=   config_migrationsrS   custom_src_tcustom_dst_trH   r   r1   r5   r   nowr   utc	isoformat)
rJ   rE   Zsrc_tZdst_tr   r   rI   Z
custom_srcZ
custom_dstr6   r   r   r   migrate   s,    
"r]   c                   @  s&   e Zd ZdZdZdZddddZdS )	JupyterMigratezA Jupyter Migration App.zjupyter-migratea  
    Migrate configuration and data from .ipython prior to 4.0 to Jupyter locations.

    This migrates:

    - config files in the default profile
    - kernels in ~/.ipython/kernels
    - notebook javascript extensions in ~/.ipython/extensions
    - custom.js/css to .jupyter/custom

    to their new Jupyter locations.

    All files are copied, not moved.
    If the destinations already exist, nothing will be done.
    Noner   c                 C  s   t  s| jd dS )zStart the application.zFound nothing to migrate.N)r]   r)   r$   )selfr   r   r   start  s    zJupyterMigrate.startN)__name__
__module____qualname____doc__rI   descriptionra   r   r   r   r   r^      s   r^   __main__)N).re   
__future__r   r   rer&   r   r   pathlibr   typingr   Ztraitlets.config.loaderr   r   Ztraitlets.logr	   Zapplicationr   pathsr   r   utilsr   r   rU   rX   rY   Zsecurity_filer   r   rW   compileregexrN   r   r*   r:   r=   rH   rS   r]   r^   Zlaunch_instancemainrb   r   r   r   r   <module>   sb      
     	0!
