U
    ꥡcU`                     @   sl  d Z ddlZddlZddl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 ejejd d	Zd
ZG dd de	ZdZeeedZejdded ejddZi Zdd Zg eg fddZej fddZ!dddZ"dd Z#ddd Z$d!d" Z%d#d$ Z&eed%d&d'd(ed)d*d+ej d,d-ed.d/d0d1e'd2d3ed4d5d6d7d8ed9d5d:d;ed<d5d=d;ed>d5d?d;ed@d5dAd;edBd5dCd;g	d	gdDdEdF Z(eedGd&dHd(ed)d*d+ej d,d-edIddJd-edKdLdMd5dNdOgdPgdDdQdR Z)eedSd&d*dTdUedVdWdXdYd&dZd[ed\d]d^d_d`dad[edbdcddd5dedOedfd4dgd5dhdOed.d/d0d1e'did3edjd5dkd;ed9d5d:d;ed<d5d=d;ed>d5d?d;ed@d5dAd;edBd5dCd;gdldm Z*eedSd&d*dndUedodpdddqd[edVdWdXdYd&dZd[ed\d]d^d_d`dad[edbdcdddrd5dedsedfd4dgd5dhdOed.d/d0d1e'did3edtdudvd5dwdOedxdydzd5d{dOed9d5d:d;g
d|d} Z+eedd~deddd&ddedddSddddedVdWdXdYd&dZd[ed\d]d^d_d`dad[edbdcdddrd5dedsedfd4dgd5dhdOed.d/d0d1e'did3eddddd[ed9d5d:d;eddde'dd3gdd Z,G dd de-Z.dd Z/dd Z0e1dkrhe2e0  dS )u   
:module: watchdog.watchmedo
:author: yesudeep@google.com (Yesudeep Mangalapilly)
:author: contact@tiger-222.fr (Mickaël Schoentgen)
:synopsis: ``watchmedo`` shell script utility.
    N)ArgumentParserRawDescriptionHelpFormatter)StringIO)dedent)WatchdogShutdown
load_class)VERSION_STRING)leveltrickszpython-pathc                       s.   e Zd ZdZdd fdd
Zdd Z  ZS )HelpFormattera#  A nicer help formatter.

    Help for arguments can be indented and contain new lines.
    It will be de-dented and arguments in the help
    will be separated by a blank line for better readability.

    Source: https://github.com/httpie/httpie/blob/2423f89/httpie/cli/argparser.py#L31
       )max_help_positionc                   s   ||d< t  j|| d S )Nr   )super__init__)selfr   argskwargs	__class__ 6/tmp/pip-unpacked-wheel-thtqfo2i/watchdog/watchmedo.pyr   5   s    zHelpFormatter.__init__c                 C   s   t | d }| S )Nz

)r   strip
splitlines)r   textwidthr   r   r   _split_lines:   s    zHelpFormatter._split_lines)__name__
__module____qualname____doc__r   r   __classcell__r   r   r   r   r   +   s   	r   zCopyright 2011 Yesudeep Mangalapilly <yesudeep@gmail.com>.
Copyright 2012 Google, Inc & contributors.

Licensed under the terms of the Apache license, version 2.0. Please see
LICENSE in the source code for more information.)epilogformatter_classz	--versionversion)actionr#   top_command)destc                  O   s   t | |fS )z^Convenience function to properly format arguments to pass to the
      command decorator.
    )list)Zname_or_flagsr   r   r   r   argumentL   s    r(   c                    s    fdd}|S )a  Decorator to define a new command in a sanity-preserving way.
      The function will be stored in the ``func`` variable when the parser
      parses arguments so that it can be called directly like so::

        >>> args = cli.parse_args()
        >>> args.func(args)

    c                    s   | j dd}t| j}j||td}|t|< | }|jdddddd	 |jd
ddddd	  D ]$}|j|d |d  |j	| d qf| S )N_-)descriptionaliasesr"   z-qz--quiet	verbosityappend_const)r&   r$   constz-vz	--verbose   r   )func)
r   replacer   r   
add_parserr   command_parsersadd_mutually_exclusive_groupadd_argumentset_defaults)r2   namedescparserZverbosity_groupargr   cmd_aliasesparentr   r   	decorator\   s*    

 
 zcommand.<locals>.decoratorr   )r   r?   r>   r@   r   r=   r   commandS   s    	rA   c                 C   s   t | |S )z
    Splits a pathname specification separated by an OS-dependent separator.

    :param pathname_spec:
        The pathname specification.
    :param separator:
        (OS Dependent) `:` on Unix and `;` on Windows or user-specified.
    )r'   split)Zpathname_spec	separatorr   r   r   
path_splitp   s    	rD   c                 C   s&   | ddd D ]}t j|| qdS )z
    Adds specified paths at specified index into the sys.path list.

    :param paths:
        A list of paths to add to the sys.path
    :param index:
        (Default 0) The index in the sys.path list where the paths will be
        added.
    Nr/   )syspathinsert)	pathnamesindexpathnamer   r   r   add_to_sys_path|   s    
rK   c              
   C   s8   ddl }t| d}|| W  5 Q R  S Q R X dS )z
    Loads the YAML configuration from the specified file.

    :param tricks_file_path:
        The path to the tricks configuration file.
    :returns:
        A dictionary of configuration information.
    r   Nrb)yamlopenZ	safe_loadread)Ztricks_file_pathnamerM   fr   r   r   load_config   s    	rQ   ;c                 C   s*   |  |}| |}|dgkr"g }||fS )zc
    Parses pattern argument specs and returns a two-tuple of
    (patterns, ignore_patterns).
     )rB   )Zpatterns_specZignore_patterns_specrC   patternsignore_patternsr   r   r   parse_patterns   s
    


rV   c                 C   s^   t |D ]}| ||| q|   ztd q&W n tk
rP   |   Y nX |   dS )al  
    Single observer thread with a scheduled path and event handler.

    :param observer:
        The observer thread.
    :param event_handler:
        Event handler which will be called in response to file system events.
    :param pathnames:
        A list of pathnames to monitor.
    :param recursive:
        ``True`` if recursive; ``False`` otherwise.
    r1   N)setschedulestarttimesleepr   stopjoin)observerZevent_handlerrH   	recursiverJ   r   r   r   observe_with   s    r`   c           
      C   sT   |D ]J}t | D ]8\}}t|}|f |}t|ddp<|}	| ||	| qqdS )ao  
    Schedules tricks with the specified observer and for the given watch
    path.

    :param observer:
        The observer thread into which to schedule the trick and watch.
    :param tricks:
        A list of tricks.
    :param pathname:
        A path name which should be watched.
    :param recursive:
        ``True`` if recursive; ``False`` otherwise.
    source_directoryN)r'   itemsr   getattrrX   )
r^   r
   rJ   r_   Ztrickr9   value
TrickClasshandlerZtrick_pathnamer   r   r   schedule_tricks   s    
rg   files*zperform tricks from given file)nargshelpz--python-path.zPaths separated by z to add to the Python path.)defaultrk   z
--intervalz	--timeouttimeoutg      ?z?Use this as the polling interval/blocking timeout (in seconds).)r&   rm   typerk   z--recursive
store_trueTz-Recursively monitor paths (defaults to True).)r$   rm   rk   z--debug-force-pollingz[debug] Forces polling.)r$   rk   z--debug-force-kqueuez[debug] Forces BSD kqueue(2).z--debug-force-winapiz[debug] Forces Windows API.z--debug-force-fseventsz[debug] Forces macOS FSEvents.z--debug-force-inotifyz [debug] Forces Linux inotify(7).)r>   c           	   	   C   s  | j rddlm} n\| jr(ddlm} nH| jr<ddlm} n4| j	rPddl
m} n | jrdddlm} nddlm} tt| j g }| jD ]}|| jd}tj|sttjttj|t|}z|t }W n$ tk
r   td	t|f Y nX t |kr
t|t   tj!|}|s,tj"t# }t$|||| j% |&  |'| qzt()d
 qRW n2 t*k
r   |D ]}|+  |,  qxY nX |D ]}|-  qdS )zE
    Command to execute tricks from a tricks configuration file.
    r   PollingObserverKqueueObserverWindowsApiObserverInotifyObserverFSEventsObserverObserverrn   zNo %r key specified in %s.r1   N).debug_force_pollingwatchdog.observers.pollingrr   debug_force_kqueuewatchdog.observers.kqueuert   debug_force_winapi)watchdog.observers.read_directory_changesrv   debug_force_inotifywatchdog.observers.inotifyrx   debug_force_fseventswatchdog.observers.fseventsrz   watchdog.observersr|   rK   rD   python_pathrh   rn   osrF   existsOSErrorerrnoENOENTstrerrorrQ   CONFIG_KEY_TRICKSKeyErrorCONFIG_KEY_PYTHON_PATHdirnamerelpathgetcwdrg   r_   rY   appendrZ   r[   r   Zunschedule_allr\   r]   )	r   r|   Z	observersZtricks_filer^   configr
   Zdir_pathor   r   r   tricks_from   sR    $
 
r   trick_pathsz5Dotted paths for all the tricks you want to generate.z--append-to-filez
                   Appends the generated tricks YAML to a file.
                   If not specified, prints to standard output.z-az--append-onlyappend_onlyz
                   If --append-to-file is not specified, produces output for
                   appending instead of a complete tricks YAML file.)r&   r$   rk   zgenerate-tricks-yamlc              	   C   s   ddl }t| j}t| t }| jD ]}t|}||  q&|	 }|
  |t|i}|dt 7 }| jdkr| js|| }tj| n8tj| js|| }t| jd}|| W 5 Q R X dS )zV
    Command to generate Yaml configuration for tricks named on the command line.
    r   Nz%s:
ab)rM   rD   r   rK   r   r   r   writeZgenerate_yamlgetvalueclosedumpr   r   Zappend_to_filer   rE   stdoutr   rF   r   rN   )r   rM   Zpython_pathsoutputZ
trick_pathre   contentheaderr   r   r   tricks_generate_yaml,  s&    


r   directoriesz%Directories to watch. (default: '.').)rj   rm   rk   z-pz	--patternz
--patternsrT   z9Matches event paths with these patterns (separated by ;).)r&   rm   rk   z-iz--ignore-patternz--ignore-patternsrU   rS   z9Ignores event paths with these patterns (separated by ;).z-Dz--ignore-directoriesignore_directorieszIgnores events for directories.z-Rr_   z%Monitors the directories recursively.z2Use this as the polling interval/blocking timeout.z--tracez!Dumps complete dispatching trace.c                    s   ddl m} ddlm} | jr@t|j |j| fddd t	| j
| j\}}|||| jd}| jrvddlm} n\| jrdd	lm} nH| jrdd
lm} n4| jrddlm} n | jrddlm} nddlm} || jd}t||| j | j! dS )z;
    Command to log file system events to the console.
    r   )echo)LoggerTrickc                    s
     | S N)info)msgZclass_module_loggerr   r   <lambda>      zlog.<locals>.<lambda>)r   )rT   rU   r   rq   rs   ru   rw   ry   r{   r}   N)"watchdog.utilsr   watchdog.tricksr   tracelogging	getLoggerr   Z
echo_classrV   rT   rU   r   r~   r   rr   r   r   rt   r   r   rv   r   r   rx   r   r   rz   r   r|   rn   r`   r   r_   )r   r   r   rT   rU   rf   r|   r^   r   r   r   log^  s0    6r   zDirectories to watch.z-cz	--commandam  
    Shell command executed in response to matching events.
    These interpolation variables are available to your command string:

        ${watch_src_path}   - event source path
        ${watch_dest_path}  - event destination path (for moved events)
        ${watch_event_type} - event type
        ${watch_object}     - 'file' or 'directory'

    Note:
        Please ensure you do not use double quotes (") to quote
        your command string. That will force your shell to
        interpolate before the command is processed by this
        command.

    Example:

        --command='echo "${watch_src_path}"'
    F)r&   rm   r$   rk   z-wz--waitwait_for_processzDWait for process to finish to avoid multiple simultaneous instances.z-Wz--dropdrop_during_processzhIgnore events that occur while command is still being executed to avoid multiple simultaneous instances.c                 C   s   ddl m} | jsd| _| jr,ddlm} nddlm} t| j	| j
\}}|| j||| j| j| jd}|| jd}t||| j| j dS )zN
    Command to execute shell commands in response to file system events.
    r   )ShellCommandTrickNrq   r{   )shell_commandrT   rU   r   r   r   r}   )r   r   rA   r~   r   rr   r   r|   rV   rT   rU   r   r   r   rn   r`   r   r_   )r   r   r|   rT   rU   rf   r^   r   r   r   r     s$    Hr   z,Long-running command to run in a subprocess.)rk   command_argsr<   z
    Command arguments.

    Note: Use -- before the command arguments, otherwise watchmedo will
    try to interpret them.
    )metavarrj   rk   z-dz--directoryZ	DIRECTORYr   zLDirectory to watch. Use another -d or --directory option for each directory.)r&   r   r$   rk   z--signalsignalSIGINTz6Stop the subprocess with this signal (default SIGINT).z--kill-after
kill_afterg      $@zYWhen stopping, kill the subprocess after the specified timeout in seconds (default 10.0).c                    s.  | j rddlm} nddlm} ddlm} ddl | jsBdg| _| j	dr\t
 | j}n
t| j} j j jh fdd	}D ]} || qt| j| j\}}| jg}|| j ||||| j|| jd
}	|	  || jd}
z2zt|
|	| j| j W n tk
r   Y nX W 5 |	  X dS )zV
    Command to start a long-running subprocess and restart it on matched events.
    r   rq   r{   )AutoRestartTrickNrl   ZSIGc                    s    D ]}  | j qtd S r   )r   SIG_IGNr   )Z_signumZ_framesignumr   Ztermination_signalsr   r   handler_termination_signalg  s    z0auto_restart.<locals>.handler_termination_signal)rA   rT   rU   r   stop_signalr   r}   )r~   r   rr   r   r|   r   r   r   r   
startswithrc   intSIGTERMr   SIGHUPrV   rT   rU   rA   extendr   r   r   rY   rn   r\   r`   r_   r   )r   r|   r   r   r   r   rT   rU   rA   rf   r^   r   r   r   auto_restart  sB    A

r   c                   @   s   e Zd ZdS )LogLevelExceptionN)r   r   r   r   r   r   r   r     s   r   c                 C   sB   t | jp
g }|dk rtd|dkr.tdddddgd	|  S )
Nr/   z&-q/--quiet may be specified only once.   z,-v/--verbose may be specified up to 2 times.ERRORWARNINGINFODEBUGr1   )sumr-   r   )r   r-   r   r   r   _get_log_level_from_args  s    r   c               
   C   s   t  } | jdkrt   dS zt| }W nN tk
rx } z0td|jd  tj	d t
| j   W Y dS d}~X Y nX td| | |  dS )zEntry-point function.Nr1   zError: r   )fileZwatchdog)cli
parse_argsr%   
print_helpr   r   printr   rE   stderrr5   r   r   setLevelr2   )r   Z	log_levelexcr   r   r   main  s    

r   __main__)r   )rR   )3r   r   r   r   os.pathrE   rZ   argparser   r   ior   textwrapr   r   r   r   Zwatchdog.versionr   basicConfigr   r   r   r   r!   r   r7   add_subparsersZ
subparsersr5   r(   rA   pathseprD   rK   rQ   rV   r`   rg   floatr   r   r   r   r   	Exceptionr   r   r   r   exitr   r   r   r   <module>   sD  

 
9
2
#D
	<
7	
