o
    \c[                     @   s   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 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Zd dlmZ d dlmZ d dlmZ G dd deeZd
S )    )gettext)DictAnyCallableTuple)AppletPlugin)Notification)SERIAL_PORT_SVCLASS_ID)RFCOMMConnectedListener)get_services)rfcomm_list)PopenN)Device)GLib)SerialServicec                   @   s@  e Zd ZU dZedZdZdddZdeded	ed
diZ	i Z
eeeedf f ed< d4ddZd4ddZd4ddZdedededdfddZdededdfddZdeddfdd Zd!ed"ed#eeef ddfd$d%Zded&ed'dddfd(d)Zded*ed+ed,ed&eddfd-d.Zdeddfd/d0Zd1eddfd2d3ZdS )5SerialManagerzbluetooth-symboliczHStandard SPP profile connection handler, allows executing custom actionswalmisz!org.blueman.plugins.serialmanagerN)schemapathscript zScript to execute on connectiona+  <span size="small">The following arguments will be passed:
Address, Name, service name, uuid16s, rfcomm node
For example:
AA:BB:CC:DD:EE:FF, Phone, DUN service, 0x1103, /dev/rfcomm0
uuid16s are returned as a comma seperated list

Upon device disconnection the script will be sent a HUP signal</span>)typedefaultnamedescz
Popen[Any]scriptsreturnc                 C   s
   i | _ d S N)r   )self r   F/usr/lib/python3/dist-packages/blueman/plugins/applet/SerialManager.pyon_load*   s   
zSerialManager.on_loadc                 C   s   | j  D ]}| | qd S r   )r   keysterminate_all_scriptsr   bdaddrr   r   r    	on_unload-   s   zSerialManager.on_unloadc                 C   s$   t d | jD ]}| | qd S )NzTerminating any running scripts)loggingdebugr   r#   r$   r   r   r    	on_delete1   s   

zSerialManager.on_deleter   keyvaluec                 C   s:   |dkr|st |d}| |d  | | d S d S d S )N	Connected)obj_pathAddress)r   r#   on_device_disconnect)r   r   r*   r+   devicer   r   r    on_device_property_changed6   s
   
z(SerialManager.on_device_property_changedserviceportc                 C   s\   |j }t|jkr,ttdtd|d |f dd  | |d |d |j|j| d S d S )NzSerial port connectedzKSerial port service on device <b>%s</b> now will be available via <b>%s</b>Aliasblueman-serial	icon_namer.   )r0   r	   
short_uuidr   _showcall_scriptr   )r   r2   r3   r0   r   r   r    on_rfcomm_connected<   s    

z!SerialManager.on_rfcomm_connectedaddressc              	   C   sp   || j vrd S | j |  D ]'}td|j  z
t|jtj W q t	y5   t
d|j  Y qw d S )NSending HUP to zNo process found for pid )r   valuesr'   infopidoskillpgsignalSIGHUPProcessLookupErrorr(   )r   r=   pr   r   r    r#   J   s   
z#SerialManager.terminate_all_scriptsrA   _condaddress_nodec                 C   s*   |\}}| j | |= td| d d S )NzScript with PID z closed)r   r'   r@   )r   rA   rH   rI   r=   noder   r   r    on_script_closedV   s   zSerialManager.on_script_closedrJ   processc                 C   s\   || j vr
i | j |< || j | v r| j | |   || j | |< t|j| j||f d S r   )r   	terminater   child_watch_addrA   rK   )r   r=   rJ   rL   r   r   r    manage_script[   s   

zSerialManager.manage_scriptr   sv_nameuuid16c           
   
   C   s   |  d}|rc|dkre|d}z%|||||d|g7 }td| t|dd d}| ||| W d S  tyb }	 z!tt|	 t	t
dt
d	|t|	f d
d  W Y d }	~	d S d }	~	ww d S d S )Nr   r    z#xc                   S   s   t ddS )Nr   )rB   setpgidr   r   r   r    <lambda>l   s    z+SerialManager.call_script.<locals>.<lambda>)
preexec_fnz$Serial port connection script failedz*There was a problem launching script %s
%sr5   r6   )
get_optionsplitr'   r(   joinr   rO   	Exceptionstrr   r9   r:   )
r   r=   r   rP   rQ   rJ   cargsrG   er   r   r    r;   e   s(   


zSerialManager.call_scriptc                 C   sP   d| }| j  D ]\}}||}|r%td|j  t|jtj	 q	d S )Nz/dev/rfcomm%ir>   )
r   itemsgetr'   r@   rA   rB   rC   rD   rE   )r   r3   rJ   r%   r   rL   r   r   r    on_rfcomm_disconnectw   s   
z"SerialManager.on_rfcomm_disconnectr0   c              	      s   dd t  D }|sd S  fddt D }|D ]+}d| }ztd|  |d | W q tjyD   tjd| dd	 Y qw d S )
Nc                 S   s   g | ]	}t |tr|qS r   )
isinstancer   ).0r2   r   r   r    
<listcomp>   s    z6SerialManager.on_device_disconnect.<locals>.<listcomp>c                    s$   g | ]}|d   d kr|d qS )dstr.   idr   )rb   rfcommr0   r   r    rc      s   $ z/dev/rfcomm%dzDisconnecting r   zFailed to disconnect T)exc_info)r   r   r'   r@   
disconnectr   Errorerror)r   r0   serial_servicesactive_portsr3   r   r   rg   r    r/      s   z"SerialManager.on_device_disconnect)r   N)__name__
__module____qualname____icon__r9   __description__
__author____gsettings__rZ   __options__r   r   __annotations__r!   r&   r)   r   r1   r   r<   r#   intr   rK   rO   r;   r`   r   r/   r   r   r   r    r      s0   
 


""
r   )r   r9   typingr   r   r   r   blueman.plugins.AppletPluginr   blueman.gui.Notificationr   blueman.Sdpr	   "blueman.plugins.applet.DBusServicer
   blueman.services.Functionsr   _bluemanr   
subprocessr   r'   rB   rD   blueman.bluez.Devicer   gi.repositoryr   blueman.services.metar   r   r   r   r   r    <module>   s     