U
    9_q                     @   s  d dl Z d dlZed d dlZd dlZd dlmZ d dlmZ d dlZd dl	T d dl
Z
d dlZeje je jd d dlZd dlZd dlmZ dZd	Zd
d Zdd ZG dd dejZedkrG dd dZed e Zee e  e Zze  W 5 e  X dS )    Nz1.9.50)GObject)GLib)*)Zdomain	localedir)StateReason<      c                 C   s:   |  ds2|  ds2|  ds2|  ds2|  dr6dS dS )Nzmoving-to-pausedZpausedZshutdownZstoppingzstopped-partlyTF)
startswith)reason r   +/usr/share/system-config-printer/monitor.pystate_reason_is_harmless'   s    
r   c                 C   s   i }z|   }W n tjk
r*   | Y S X | D ]V\}}|d }|D ]@}|dkrX q4t|rbqH||krrg ||< || t||| qHq4|S )Nprinter-state-reasonsnone)getPrinterscupsIPPErroritemsr   appendr   )Z
connectionppdcacheresultprintersnameprinterreasonsr
   r   r   r   collect_printer_state_reasons0   s     
r   c                   @   s  e Zd ZejjddfejjddfejjdejffejjdejffejjdejffejjdeffejjdeeejejffejjdeeejejffejjdeeejffejjdeffejjdeeejffejjdeffejjddfejjddfejjdeeffdZ	dZ
dZd'ddZd	d
 Zdd Zdd Zdd Zdd Zdd Zi fddZe i fddZdd Zd(ddZdd Zd)dd Zd!d" Zd#d$ Zd%d& ZdS )*MonitorNr   )refreshmonitor-exitedstate-reason-addedstate-reason-removedstill-connectingnow-connected	job-added	job-eventjob-removedprinter-addedprinter-eventprinter-removedcups-connection-errorcups-connection-recoveredcups-ipp-errorz/com/redhat/PrinterSpoolerzcom.redhat.PrinterSpoolerTc                 C   s<  t j |  || _|| _|| _i | _i | _t | _d| _	d | _
d| _|rRt| |r`t| |rnt| t | _t | _t | _t | _tj| j| j| jd| _d| _i | _i | _t | _i | _d| _d | _ |d krzt!" }W n t!j#j$k
r
   Y nX || _%|d k	r2|j&| j'| j(| j)d d| _*d S )NTFhostport
encryptionznot-completedpathZdbus_interface)+r   __init__my_jobsspecific_destsmonitor_jobsjobsprinter_state_reasonssetr   process_pending_eventsfetch_jobs_timercups_connection_in_errorr   Z	setServerZsetPortZsetEncryptiongetUseruserZ	getServerr-   ZgetPortr.   ZgetEncryptionr/   r   ZPPDCache
which_jobsreasons_seenconnecting_timersstill_connectingconnecting_to_devicereceived_any_dbus_signalsupdate_timerdbusZ	SystemBus
exceptionsZDBusExceptionbusZadd_signal_receiverhandle_dbus_signal	DBUS_PATH
DBUS_IFACEsub_id)selfrH   r4   r5   r6   r-   r.   r/   r   r   r   r3   k   sV    








zMonitor.__init__c                 C   s
   | j  S N)r   copyrM   r   r   r   get_printers   s    zMonitor.get_printersc                 C   s
   | j  S rN   )r7   rO   rP   r   r   r   get_jobs   s    zMonitor.get_jobsc                 C   s   | j S rN   )r   rP   r   r   r   get_ppdcache   s    zMonitor.get_ppdcachec                 C   s   | j dkrjt }z@t| j tj| j| j| jd}|	| j  t
d| j   W n   Y nX t| | jd k	r| jj| j| j| jd t| j }| j| jfD ]}|r|| q|D ]}t| q| d d S )Nr2   r,   Canceled subscription %dr0   r   )rL   r   r=   setUserr>   
Connectionr-   r.   r/   cancelSubscription
debugprintrH   Zremove_signal_receiverrI   rJ   rK   listrA   valuesrE   r;   r   r   source_removeemit)rM   r>   cZtimerstimerr   r   r   cleanup   s2    



zMonitor.cleanupc                 C   s
   || _ d S rN   )r:   )rM   Zwhetherr   r   r   set_process_pending   s    zMonitor.set_process_pendingc                 C   s\   | j s$td| j|}|| j|< dS || jkr6| j|= td|  |  \}}| | dS )z8Timer callback to check on connecting-to-device reasons.   Fz%Still-connecting timer fired for `%s')r:   r   timeout_addcheck_still_connectingrA   rX   sort_jobs_by_printerupdate_connecting_devices)rM   r   r^   printer_jobsmy_printersr   r   r   rc      s    



zMonitor.check_still_connectingc                 C   s  t   }i }d}| j D ]>\}}d}|D ]}| dkr,d}	||i  D ](\}
}|dtj}|tjkrPd}	 qzqP|	std q,|	 }| j
||}|||< td||   || tkr|	r|| jkr| j| | d| || jkrt| j|  | j|= td|  d} q(q,|r|| jkrt| j|  | j|= td|  qt }| jD ]V}||krh|| | d	| || jkrht| j|  | j|= td|  qh| j|| _|| _
d
S )z;Updates connecting_to_device dict and still_connecting set.FTconnecting-to-device	job-statez%Ignoring stale connecting-to-device xzConnecting time: %dr!   z!Stopped connecting timer for `%s'r"   N)timer8   r   
get_reasongetr   IPP_JOB_CANCELEDIPP_JOB_PROCESSINGrX   get_printerrC   CONNECTING_TIMEOUTrB   addr\   rA   r   r[   r9   
difference)rM   rf   Ztime_nowrC   Ztroubler   r   Z	connectedr
   have_processing_jobjobdatastatetremover   r   r   re      sh    




z!Monitor.update_connecting_devicesc                    sl  t  j }t } j D ]\}}|D ]}| }| }|| | jkrpt	
 fdd| | j|< | dkr*| jkr*d}	||i  D ](\}
}|dtj}|tjkrd}	 qq|	rt	dt  j|}| j|< td|  q*td	 t r*tt| q*q | t  j }|D ]6}||kr0 j| } j|= t	
 fd
d| q0d S )Nc                    s     d| S )Nr   r\   xrP   r   r   <lambda>   s    z-Monitor.check_state_reasons.<locals>.<lambda>rh   Fri   Tr   zStart connecting timer for `%s'z#Ignoring stale connecting-to-devicec                    s     d| S )Nr    ry   rz   rP   r   r   r|   F      )rY   r@   keysr9   r8   r   Z	get_tuplero   rq   r   idle_addrk   rC   rl   r   rm   rn   timeout_add_secondsrp   rc   rA   rX   get_debuggingpprintpformatre   )rM   rg   rf   Zold_reasons_seen_keysZreasons_nowr   r   r
   tuplers   rt   ru   rv   rw   r   r   rP   r   check_state_reasons  sZ    







zMonitor.check_state_reasonsc                 C   s  | j rt| j  d | _ | js:td| j| _ td dS td t }zt	| j
 tj| j| j| jd}zDz|| jg| jd g}W n" tk
r   || jg}Y nX W n tjk
rZ } z|j\}}t	| |tjkrd| _td |   W Y HW dS | d	|| |tjkr2W Y "W dS td
||f  W Y W dS d }~X Y nX W n: tk
r   t	| td d| _| d Y dS X | jrd| _td | d t	| | j }|d D ]}|d }|| _|d }	td||	|d f  t rtt| |	 dr`|d }
|	dkrb|
| j!krb| j!"|
 | d|
 n|	dkr|
| j!kr| j!#|
 t$| j%& }|D ]2}|d |
kr| j%| }| j%|= | d| q|
| j'kr| j'|
= | d|
 np|
| j!kr|d }g }|D ]8}|dkr qBt(|r*q|)t*|
|| j+ q|| j'|
< | d|
|	| q|	 dstdt,|	  q|d }|	d ks|	d!kr||kr|d" tj-kr| j.d k	r|d | j.kr֐qz6|/|}| j0r|d# t krW q|||< W nj t1k
r.   d$d%i||< Y nJ tjk
rv } z(|j\}}| d	|| d$d%i||< W 5 d }~X Y nX | d&||	|||   nf|	d'ks|	d!kr|d" tj2kr| j3d(krz||= | d)||	| W n t1k
r   Y nX qz|| }W n t1k
r"   Y qY nX | j.d k	rZ|d | j.krZ||= | d)||	| qd*D ]}|| ||< q^d+|kr|d+ |d,< | d-||	||  q| 4d | 5| || _| 4d | j6s|d. }t7|| j}td/|  || _ dS )0Nra   z#Deferred get_notifications by 200msFget_notificationsr,   r   r2   z$Subscription not found, will refreshr+   z$getNotifications failed with %d (%s)Tz!cups-connection-error, will retryr)   r*   eventsznotify-sequence-numberznotify-subscribed-eventz%d %s %sznotify-textzprinter-zprinter-namer&   printer-deletedr    r(   r   r   r'   zjob-zUnhandled nse %sznotify-job-idjob-createdjob-state-changedri   job-originating-user-namejob-k-octetsr   r#   job-completed)	completedallr%   )ri   job-nameznotify-printer-urijob-printer-urir$   znotify-get-intervalNext notifications fetch in %ds)8rE   r   r[   r:   rb   r   rX   r   r=   rU   r>   rV   r-   r.   r/   ZgetNotificationsrL   sub_seqAttributeErrorr   argsZIPP_NOT_FOUNDr   r\   ZIPP_FORBIDDENRuntimeErrorr<   r7   rO   r   r   r   r	   r   rq   rx   rY   r@   r~   r8   r   r   r   r   reprrn   r5   ZgetJobAttributesr4   KeyErrorZIPP_JOB_COMPLETEDr?   r`   update_jobsrD   r   )rM   r>   r]   Znotificationsemr7   eventseqZnser   r   r   r
   r8   r   jobidZattrsrt   Z	attributeZintervalrw   r   r   r   r   I  s4   






















zMonitor.get_notificationsc              
      s  t d  d |d k	r | _t }z&t j tj j j	 j
d}W n. tk
r|   t jd t| Y d S X  jdkrz| j W nD tjk
r } z$|j\}}t fdd|| W 5 d }~X Y nX  jrt j d  _t d j  z `W n tk
r$   Y nX dd	d
dg} jrN|dddddg z*|jd|d _t d jt|f  W nF tjk
r } z$|j\}}t fdd|| W 5 d }~X Y nX t|  jdkr jrt j tt j _t dt   jr j } jdkr^i }	| D ](\}
}| dtj!tj!k r0||	|
< q0|	}d _" j#rxt j# t$d j%| _#ni }z,t&| j'}| _(|) }t*|+  _,W np tjk
r } z*|j\}}t fdd|| W Y d S d }~X Y n& tk
r,   t jd Y d S X  j-d k	r|+ D ]B}
||
  dd}|.d}||d d  }| j-krB||
= qB /d  j,D ]}t fdd| q| D ] \}
}t fdd|
| q 0| | _ /d dS ) Nr   r,   r)   r2   c                    s     d| |S Nr+   ry   r   r   rP   r   r   r|     r}   z!Monitor.refresh.<locals>.<lambda>rT   r&   zprinter-modifiedr   zprinter-state-changedr   r   zjob-stoppedr   zjob-progress/)r   z"Created subscription %d, events=%sc                    s     d| |S r   ry   r   rP   r   r   r|   .  r}   r   )r   r   ri   r      c                    s     d| |S r   ry   r   rP   r   r   r|   W  r}   r   Fc                    s     d| S )Nr&   ry   rz   rP   r   r   r|   h  r}   c                    s     d| di |S )Nr#    ry   )r   rt   rP   r   r   r|   j  s    T)1rX   r\   r?   r   r=   rU   r>   rV   r-   r.   r/   r   r   r   rL   rW   r   r   rE   r[   r   r   r6   extendZcreateSubscriptionr   r   MIN_REFRESH_INTERVALr   r7   rO   r   rl   rm   fetch_first_job_idr;   rb   
fetch_jobsr   r   r8   r   r9   r~   r   r5   rfindr`   r   )rM   r?   refresh_allr>   r]   r   r   r   r7   Zfilteredr   rt   rZdestsuriir   r   rP   r   r     s    



 
 



 



 

zMonitor.refreshc              
   C   s  | j s
dS t }z&t| j tj| j| j| jd}W n0 t	k
rh   | 
d d | _t| Y dS X d}dddd	d
ddg}z|j| j| j| j||d}W nR tjk
r } z2|j\}}| 
d|| d | _t| W Y dS d }~X Y nX t| t|}	td|	|f  | j }
t| }|  |	dkr|||	d  }|| jk r| j| d }tdt|  td n| j| d }t| j|d D ]}z|| }| jd k	r|dd}|d}||d d  }|| jkrt||
krd}nd}||
|< | 
||di |  W n6 tk
rT   ||
krP|
|= | 
d|di  Y nX qt|
 }|  |	|k rd}tt|D ]>}|| }|s||krd}|r|
|= | 
d|di  q| |
 |
| _|	|k rd | _dS |d }|s|| jkr|d7 }q|| _dS )NTr,   r)   Fr   zjob-idr   ri   r   r   r   ztime-at-creation)r?   r4   Zfirst_job_idlimitZrequested_attributesr+   zGot %s jobs, asked for %sr   zUnexpected job IDs returned: %szThat's not what we asked for!r   r$   r#   r   r%   ) r:   r   r=   rU   r>   rV   r-   r.   r/   r   r\   r;   ZgetJobsr?   r4   r   r   r   lenrX   r7   rO   rY   r~   sortr   ranger5   rl   r   r   r   )rM   r   r>   r]   r   r   Zfetchedr   r   Zgotr7   ZjobidsZ
last_jobidr   rt   r   r   r   nZtrimnextr   r   r   r   r  s    















zMonitor.fetch_jobsc           
      C   s   |d kr| j }t }i }| D ]x\}}|dtj}|tjkrBq |dd}|d}|dkrbq ||d d  }	||	 |	|kri ||	< |||	 |< q ||fS )Nri   r   r   r   r2   r   )r7   r9   r   rl   r   rm   r   rq   )
rM   r7   rg   rf   rt   ru   rv   r   r   r   r   r   r   rd     s$    


zMonitor.sort_jobs_by_printerc                 C   s&   t d | |\}}| || d S )Nr   )rX   rd   r   )rM   r7   rf   rg   r   r   r   r     s    zMonitor.update_jobsc                 C   s.   | j rt| j  td| j| _ td d S )Nra   z1Next notifications fetch in 200ms (update called))rE   r   r[   rb   r   rX   rP   r   r   r   update  s    zMonitor.updatec                 G   s    t d |   | jsd| _d S )Nz(D-Bus signal from CUPS... calling updateT)rX   r   rD   )rM   r   r   r   r   rI     s    zMonitor.handle_dbus_signal)NTNTNNN)NT)N)__name__
__module____qualname__r   ZSignalFlagsZRUN_LASTZTYPE_PYOBJECTstrintZ__gsignals__rJ   rK   r3   rQ   rR   rS   r_   r`   rc   re   r9   r   r   r   r   rd   r   r   rI   r   r   r   r   r   C   s   $         
2=4 0
zj
r   __main__c                   @   s|   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd ZdS )SignalWatcherc                 C   s   | d| j | d| j | d| j | d| j | d| j | d| j | d| j | d| j | d	| j	 | d
| j
 | d| j | d| j | d| j d S )Nr   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r+   )Zconnecton_monitor_exitedon_state_reason_addedon_state_reason_removedon_still_connectingon_now_connectedon_job_addedon_job_eventon_job_removedon_printer_addedon_printer_eventon_printer_removedon_cups_connection_erroron_cups_ipp_error)rM   Zmonitorr   r   r   r3     s"    zSignalWatcher.__init__c                 C   s   t d|  d S )Nz*%s: monitor exitedprintrM   objr   r   r   r     s    zSignalWatcher.on_monitor_exitedc                 C   s   t d||f  d S )Nz*%s: +%sr   rM   r   r
   r   r   r   r     s    z#SignalWatcher.on_state_reason_addedc                 C   s   t d||f  d S )Nz*%s: -%sr   r   r   r   r   r     s    z%SignalWatcher.on_state_reason_removedc                 C   s   t d||f  d S )Nz*%s: still connecting: %sr   r   r   r   r   r      s    z!SignalWatcher.on_still_connectingc                 C   s   t d||f  d S )Nz*%s: now connected: %sr   )rM   r   r   r   r   r   r   #  s    zSignalWatcher.on_now_connectedc                 C   s   t d||f  d S )Nz*%s: job %d addedr   rM   r   r   	eventnamer   Zjobdatar   r   r   r   &  s    zSignalWatcher.on_job_addedc                 C   s   t d|||f  d S )Nz*%s: job %d event: %sr   r   r   r   r   r   )  s    zSignalWatcher.on_job_eventc                 C   s   t d|||f  d S )Nz*%s: job %d removed (%s)r   )rM   r   r   r   r   r   r   r   r   ,  s    zSignalWatcher.on_job_removedc                 C   s   t d||f  d S )Nz*%s: printer added: %sr   rM   r   r   r   r   r   r   /  s    zSignalWatcher.on_printer_addedc                 C   s   t d|||f  d S )Nz*%s: printer event: %s: %sr   )rM   r   r   r   r   r   r   r   r   2  s    zSignalWatcher.on_printer_eventc                 C   s   t d||f  d S )Nz*%s: printer %s removedr   r   r   r   r   r   5  s    z SignalWatcher.on_printer_removedc                 C   s   t d|  d S )Nz*%s: cups connection errorr   r   r   r   r   r   8  s    z&SignalWatcher.on_cups_connection_errorc                 C   s   t d|||f  d S )Nz*%s: IPP error (%d): %sr   )rM   r   errZ	errstringr   r   r   r   ;  s    zSignalWatcher.on_cups_ipp_errorN)r   r   r   r3   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s   r   T) Zconfigr   ZrequirerF   Z	dbus.glibZgi.repositoryr   r   rj   debugr   gettextinstallZPACKAGEr   r   Zstatereasonr   rp   r   r   r   r   r   r   Zset_debuggingr   r   ZMainLoopZloopr_   runr   r   r   r   <module>   sD   
	     F
9