U
    1^                     @   s   d Z ddlmZ ddlmZmZmZ ddlmZ ddl	Z	ddl
Z
ddlZedZe
dZeZeZG dd	 d	ZG d
d deZdS )z.
utils.plugins - Plugin loading functionality
    )Path)ListDictUnion)
ModuleTypeNzplugin-loaderz\* depends: (.+)c                   @   sr   e Zd ZdZdeee dddZedddd	Z	de
eef eed
ddZddddZee dddZdS )PluginLoaderz
    Infobot's plugin loader.

    Generates a dependency graph and returns a list of loaded modules when
    load_all() is called.
    pluginsN)plugin_directory	blacklistc                 C   s   | | _ | _i | _t|pg | _t| j}g }| D ]:}| rN|d  sZ|j	
dr6|j| jkr6|| q6|D ]}| | qvdS )z? Initializes the PluginLoader by generating a dependency graph __init__.pyz.pyN)plugin_packager	   graphsetr
   r   Ziterdiris_direxistsnameendswithstemappendparse_depends)selfr	   r
   pathZplugin_pathsZsubpath r   8/home/sam/code/telegram-teamspeak-bridge/core/plugins.py__init__   s    

zPluginLoader.__init__)r   returnc              	   C   s   |  rt|d }nt|}t|~}|D ]T}d|kr\td|j d  W 5 Q R  d S t|}|r,|d	d| j
|< q,|| j
kr|jdkrg | j
|< W 5 Q R X d S )Nr   z* noloadzNot loading plugin z due to noload directive   , )r   stropenloggerinfor   
DEPENDS_REsearchgroupsplitr   r   )r   r   Z	main_filepluginlinematchr   r   r   r   +   s    

zPluginLoader.parse_depends)plugin_pathr   r   c                 C   s2   |s$t |tst| j d|j }t|}|S )N.)
isinstancer   AssertionErrorr   r   	importlibimport_module)r   r)   r   r&   r   r   r   load_plugin@   s
    
zPluginLoader.load_plugin)r   c              	   C   sb   | j  D ]R\}}t|| j@ }|r
t|dkr4dnd}td|j dd| d| dq
d S )	Nr   ZareiszPlugin z
 requires r   z, which z blacklisted.)r   itemsr   r
   lenDependencyErrorr   join)r   r&   depsZblacklisted_depsZ	verb_formr   r   r   check_impossible_loadsH   s
    z#PluginLoader.check_impossible_loadsc              
   C   s   |    g }| jddd | jrdd | j D }| D ]Z\}}|| | | j|= | j D ].\}}z||j W qf tk
r   Y qfX qfq<qt	dt
| d| d |S )	Nr   r   )r   c                 S   s   i | ]\}}|s||qS r   r   ).0r&   r5   r   r   r   
<dictcomp>V   s     z)PluginLoader.load_all.<locals>.<dictcomp>zLoaded z
 plugins ())r6   r/   r   r1   r   remover   
ValueErrorr    r!   r2   )r   r   Zsatisfied_pluginsZsatisfied_plugin_r&   r5   r   r   r   load_allP   s    zPluginLoader.load_all)r   N)N)__name__
__module____qualname____doc__r   r   Pluginr   r   r   r   r   r/   r6   r=   r   r   r   r   r      s   r   c                   @   s   e Zd ZdS )r3   N)r>   r?   r@   r   r   r   r   r3   g   s   r3   )rA   pathlibr   typingr   r   r   typesr   r-   relogging	getLoggerr    compiler"   r   rB   Z
Dependencyr   	Exceptionr3   r   r   r   r   <module>   s   

T