3
Zq              
   @   s  d dl Z d dlZej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j  ej Zzej  W dej  X dS )    Nz1.9.50)GObject)GLib)*)Zdomain	localedir)StateReason<      c             C   s:   | j ds2| j ds2| j ds2| j ds2| j 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 }y| j  }W n tjk
r&   |S X xd|j D ]X\}}|d }xF|D ]>}|dkrVP t|r`qH||krpg ||< || jt||| qHW q2W |S )Nz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f fejjdf 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f fejjdf 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 ))MonitorN)refreshzmonitor-exitedzstate-reason-addedzstate-reason-removedzstill-connectingznow-connectedz	job-addedz	job-eventzjob-removedzprinter-addedzprinter-eventzprinter-removedzcups-connection-errorzcups-connection-recoveredzcups-ipp-errorz/com/redhat/PrinterSpoolerzcom.redhat.PrinterSpoolerTc             C   s<  t j j|  || _|| _|| _i | _i | _t | _d| _	d | _
d| _|rRtj| |r`tj| |rntj| tj | _tj | _tj | _tj | _tj| j| j| jd| _d| _i | _i | _t | _i | _d| _d | _ |d kryt!j" }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)pathdbus_interfacer   )+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)selfr8   r$   r%   r&   r   r   r   r   r   r   r#   k   sR    









zMonitor.__init__c             C   s
   | j j S )N)r   copy)r=   r   r   r   get_printers   s    zMonitor.get_printersc             C   s
   | j j S )N)r'   r>   )r=   r   r   r   get_jobs   s    zMonitor.get_jobsc             C   s   | j S )N)r   )r=   r   r   r   get_ppdcache   s    zMonitor.get_ppdcachec             C   s   | j dkrjtj }y@tj| j tj| j| j| jd}|j	| j  t
d| j   W n   Y nX tj| | jd k	r| jj| j| j| jd t| jj }x"| j| jgD ]}|r|j| qW x|D ]}tj| qW | jd d S )Nr   )r   r   r   zCanceled subscription %d)r    r!   zmonitor-exitedr"   )r<   r   r-   setUserr.   
Connectionr   r   r   cancelSubscription
debugprintr8   Zremove_signal_receiverr9   r:   r;   listr1   valuesr5   r+   r   r   source_removeemit)r=   r.   cZtimerstimerr   r   r   cleanup   s.    






zMonitor.cleanupc             C   s
   || _ d S )N)r*   )r=   Zwhetherr   r   r   set_process_pending   s    zMonitor.set_process_pendingc             C   s\   | j s$tjd| j|}|| j|< dS || jkr6| j|= td|  | j \}}| j| dS )z8Timer callback to check on connecting-to-device reasons.   Fz%Still-connecting timer fired for `%s')r*   r   timeout_addcheck_still_connectingr1   rE   sort_jobs_by_printerupdate_connecting_devices)r=   r   rK   printer_jobsmy_printersr   r   r   rP      s    



zMonitor.check_still_connectingc             C   s  t j  }i }d}xR| jj D ]B\}}d}x |D ]}|j dkr4d}	x:|j|i j D ]&\}
}|jdtj}|tjkrZd}	P qZW |	std q4|j	 }| j
j||}|||< td||   || tkr&|	r&|| jkr| jj| | jd| || jkr&tj| j|  | j|= td|  d}P q4W |r|| jkrtj| j|  | j|= td|  qW t }x`| jD ]V}||krt|j| | jd	| || jkrttj| j|  | j|= td|  qtW | jj|| _|| _
d
S )z;Updates connecting_to_device dict and still_connecting set.FTzconnecting-to-devicez	job-statez%Ignoring stale connecting-to-device xzConnecting time: %dzstill-connectingz!Stopped connecting timer for `%s'znow-connectedN)timer(   r   
get_reasongetr   IPP_JOB_CANCELEDIPP_JOB_PROCESSINGrE   get_printerr3   CONNECTING_TIMEOUTr2   addrI   r1   r   rH   r)   
difference)r=   rS   Ztime_nowr3   Ztroubler   r   Z	connectedr
   have_processing_jobjobdatastatetremover   r   r   rR      sb    



z!Monitor.update_connecting_devicesc                s|  t  jj }t }x jj D ]\}}x|D ]}|j }|j }|j| | jkrvt	j
 fdd| | j|< |j dko| jkr0d}	x:|j|i j D ]&\}
}|jdtj}|tjkrd}	P qW |	rt	jdt  j|}| j|< td|  q0td	 t r0ttj| q0W q"W  j| t  jj }x>|D ]6}||kr> j| } j|= t	j
 fd
d| q>W d S )Nc                s    j d| S )Nzstate-reason-added)rI   )x)r=   r   r   <lambda>   s    z-Monitor.check_state_reasons.<locals>.<lambda>zconnecting-to-deviceFz	job-stateTr   zStart connecting timer for `%s'z#Ignoring stale connecting-to-devicec                s    j d| S )Nzstate-reason-removed)rI   )rd   )r=   r   r   re   F  s    )rF   r0   keysr)   r(   r   Z	get_tuplerZ   r\   r   idle_addrV   r3   rW   r   rX   rY   timeout_add_secondsr[   rP   r1   rE   get_debuggingpprintpformatrR   )r=   rT   rS   Zold_reasons_seen_keysZreasons_nowr   r   r
   tupler^   r_   r`   ra   rb   r   r   )r=   r   check_state_reasons  sN    











zMonitor.check_state_reasonsc          1   C   s  | j rtj| j  d | _ | js:tjd| j| _ td dS td tj } ytj	| j
 tj| j| j| jd}yDy|j| jg| jd g}W n" tk
r   |j| jg}Y nX W n tjk
r@ } zl|j\}}tj	| |tjkrd0| _td | j  dS | jd|| |tjkr"dS td	||f  d
S d }~X nX W n8 tk
r|   tj	| td d
| _| jd d
S X | jrd| _td | jd tj	| | jj }x|d D ]}|d }|| _|d }	td||	|d f  t rttj| |	j drL|d }
|	dkrJ|
| j!krJ| j!j"|
 | jd|
 n|	dkr|
| j!kr| j!j#|
 t$| j%j& }x:|D ]2}|d |
kr| j%| }| j%|= | jd| qW |
| j'kr| j'|
= | jd|
 np|
| j!kr|d }g }x<|D ]4}|dkrP t(|rq|j)t*|
|| j+ qW || j'|
< | jd|
|	| q|	j dslt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qy4|j/|}| j0r|d" tj krw|||< W nj t1k
r   d#d$i||< Y nJ tjk
r` } z*|j\}}| jd|| d#d$i||< W Y d d }~X nX | jd%||	||| j  nf|	d&ks|	d kr|d! tj2kr| j3d1kry||= | jd)||	| W n t1k
r   Y nX qy|| }W n t1k
r
   wY nX | j.d k	rB|d | j.krB||= | jd)||	| qxd2D ]}|| ||< qHW d+|krt|d+ |d,< | jd-||	||j  qW | j4d | j5| || _| j4d
 | j6s|d. }tj7|| j}td/|  || _ dS )3NrN   z#Deferred get_notifications by 200msFget_notifications)r   r   r   r   z$Subscription not found, will refreshzcups-ipp-errorz$getNotifications failed with %d (%s)Tz!cups-connection-error, will retryzcups-connection-errorzcups-connection-recoveredeventsznotify-sequence-numberznotify-subscribed-eventz%d %s %sznotify-textzprinter-zprinter-namezprinter-addedzprinter-deletedzstate-reason-removedzprinter-removedzprinter-state-reasonsr   zprinter-eventzjob-zUnhandled nse %sznotify-job-idzjob-createdzjob-state-changed	job-statezjob-originating-user-namezjob-k-octetsr   z	job-addedzjob-completed	completedallzjob-removedjob-nameznotify-printer-urizjob-printer-uriz	job-eventznotify-get-intervalzNext notifications fetch in %dsr"   )rq   rr   )rp   rs   )8r5   r   rH   r*   rO   rn   rE   r   r-   rB   r.   rC   r   r   r   ZgetNotificationsr<   sub_seqAttributeErrorr   argsZIPP_NOT_FOUNDr   rI   ZIPP_FORBIDDENRuntimeErrorr,   r'   r>   ri   rj   rk   r	   r   r\   rc   rF   r0   rf   r(   r   r   r   r   reprrY   r%   ZgetJobAttributesr$   KeyErrorZIPP_JOB_COMPLETEDr/   rM   update_jobsr4   rh   )r=   r.   rJ   Znotificationsemr'   eventseqZnser   r   rl   r
   r(   r   jobidZattrsr_   Z	attributeZintervalrb   r   r   r   rn   I  s   




























zMonitor.get_notificationsc          ?      s  t d  jd |d k	r | _tj }y&tj j tj j j	 j
d}W n, tk
rz   tj jd tj| d S X  jd kry|j j W nD tjk
r } z&|j\}}tj fdd|| W Y d d }~X nX  jrtj j d  _t d j  y `W n tk
r"   Y nX dd	d
dg} jrL|jdddddg y*|jd|d _t d jt|f  W nF tjk
r } z&|j\}}tj fdd|| W Y d d }~X nX tj|  jd!kr jrtj j tjt j _t dt   jr jj } jd"kr`i }	x4|j D ](\}
}|j dtj!tj!k r0||	|
< q0W |	}d _" j#rztj j# tj$d j%| _#ni }y,t&| j'}| _(|j) }t*|j+  _,W nf tjk
r } z$|j\}}tj fdd|| d S d }~X n$ tk
r$   tj jd d S X  j-d k	rxN|j+ D ]B}
||
 j dd}|j.d}||d d  }| j-kr<||
= q<W  j/d x$ j,D ]}tj fdd| qW x,|j D ] \}
}tj fdd|
| qW  j0| | _ j/d dS )#Nr   )r   r   r   zcups-connection-errorr   c                s    j d| |S )Nzcups-ipp-error)rI   )r{   r|   )r=   r   r   re     s    z!Monitor.refresh.<locals>.<lambda>zCanceled subscription %dzprinter-addedzprinter-modifiedzprinter-deletedzprinter-state-changedzjob-createdzjob-completedzjob-stoppedzjob-state-changedzjob-progress/)ro   z"Created subscription %d, events=%sc                s    j d| |S )Nzcups-ipp-error)rI   )r{   r|   )r=   r   r   re   .  s    zNext notifications fetch in %dsrr   rq   z	job-state   c                s    j d| |S )Nzcups-ipp-error)rI   )r{   r|   )r=   r   r   re   W  s    zjob-printer-uriFc                s    j d| S )Nzprinter-added)rI   )rd   )r=   r   r   re   h  s    c                s    j d| di |S )Nz	job-added )rI   )r   r_   )r=   r   r   re   j  s    Tr"   r"   )rr   rq   )1rE   rI   r/   r   r-   rB   r.   rC   r   r   r   rw   r   rg   r<   rD   r   rv   r5   rH   rt   ru   r&   extendZcreateSubscriptionrx   rh   MIN_REFRESH_INTERVALrn   r'   r>   r   rW   rX   fetch_first_job_idr+   rO   
fetch_jobsr   r   r(   r   r)   rf   r   r%   rfindrM   rz   )r=   r/   refresh_allr.   rJ   r{   r|   ro   r'   Zfilteredr   r_   rZdestsuriir   r   )r=   r   r     s    













zMonitor.refreshc          #   C   s"  | j s
dS tj }y&tj| j tj| j| j| jd}W n. t	k
rf   | j
d d | _tj| dS X d}dddd	d
ddg}y|j| j| j| j||d}W nJ tjk
r } z,|j\}}| j
d|| d | _tj| dS d }~X nX tj| t|}	td|	|f  | jj }
t|j }|j  |	dkrr||	d  }|| jk r| j| d }tdt|  td n| j| d }xt| j|d D ]}y|| }| jd k	r|jdd}|jd}||d d  }|| jkrt||
krd}nd}||
|< | j
||di |j  W n6 tk
rL   ||
krH|
|= | j
d|di  Y nX qW t|
j }|j  |	|k rd}xPtt|D ]@}|| }| r||krd}|r|
|= | j
d|di  qW | j|
 |
| _|	|k rd | _dS |d }x"| r|| jkr|d7 }qW || _dS )NT)r   r   r   zcups-connection-errorFr   zjob-idzjob-printer-uriz	job-statezjob-originating-user-namezjob-k-octetszjob-nameztime-at-creation)r/   r$   Zfirst_job_idlimitZrequested_attributeszcups-ipp-errorzGot %s jobs, asked for %sr   zUnexpected job IDs returned: %szThat's not what we asked for!r   z	job-eventz	job-addedr   zjob-removed) r*   r   r-   rB   r.   rC   r   r   r   rw   rI   r+   ZgetJobsr/   r$   r   r   rv   lenrE   r'   r>   rF   rf   sortrx   ranger%   rW   r   ry   rz   )r=   r   r.   rJ   r   r   Zfetchedr{   r|   Zgotr'   ZjobidsZ
last_jobidr   r_   r   r   r   nZtrimnextr   r   r   r   r  s    













zMonitor.fetch_jobsc       
      C   s   |d kr| j }t }i }x|j D ]x\}}|jdtj}|tjkrDq"|jdd}|jd}|dkrdq"||d d  }	|j|	 |	|kri ||	< |||	 |< q"W ||fS )Nz	job-statezjob-printer-urir   r   r   r"   )r'   r)   r   rW   r   rX   r   r\   )
r=   r'   rT   rS   r_   r`   ra   r   r   r   r   r   r   rQ     s$    


zMonitor.sort_jobs_by_printerc             C   s&   t d | j|\}}| j|| d S )Nrz   )rE   rQ   rm   )r=   r'   rS   rT   r   r   r   rz     s    zMonitor.update_jobsc             C   s.   | j rtj| j  tjd| j| _ td d S )NrN   z1Next notifications fetch in 200ms (update called))r5   r   rH   rO   rn   rE   )r=   r   r   r   update  s    zMonitor.updatec             G   s    t d | j  | jsd| _d S )Nz(D-Bus signal from CUPS... calling updateT)rE   r   r4   )r=   rv   r   r   r   r9     s    zMonitor.handle_dbus_signal)NTNTNNN)NT)N)__name__
__module____qualname__r   ZSignalFlagsZRUN_LASTZTYPE_PYOBJECTstrintZ__gsignals__r:   r;   r#   r?   r@   rA   rL   rM   rP   rR   r)   rm   rn   r   r   rQ   rz   r   r9   r   r   r   r   r   C   sj     
0=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   |j d| j |j d| j |j d| j |j d| j |j d| j |j d| j |j d| j |j d| j |j d	| j	 |j d
| j
 |j d| j |j d| j |j d| j d S )Nzmonitor-exitedzstate-reason-addedzstate-reason-removedzstill-connectingznow-connectedz	job-addedz	job-eventzjob-removedzprinter-addedzprinter-eventzprinter-removedzcups-connection-errorzcups-ipp-error)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)r=   Zmonitorr   r   r   r#     s    zSignalWatcher.__init__c             C   s   t d|  d S )Nz*%s: monitor exited)print)r=   objr   r   r   r     s    zSignalWatcher.on_monitor_exitedc             C   s   t d||f  d S )Nz*%s: +%s)r   )r=   r   r
   r   r   r   r     s    z#SignalWatcher.on_state_reason_addedc             C   s   t d||f  d S )Nz*%s: -%s)r   )r=   r   r
   r   r   r   r     s    z%SignalWatcher.on_state_reason_removedc             C   s   t d||f  d S )Nz*%s: still connecting: %s)r   )r=   r   r
   r   r   r   r      s    z!SignalWatcher.on_still_connectingc             C   s   t d||f  d S )Nz*%s: now connected: %s)r   )r=   r   r   r   r   r   r   #  s    zSignalWatcher.on_now_connectedc             C   s   t d||f  d S )Nz*%s: job %d added)r   )r=   r   r   	eventnamer}   jobdatar   r   r   r   &  s    zSignalWatcher.on_job_addedc             C   s   t d|||f  d S )Nz*%s: job %d event: %s)r   )r=   r   r   r   r}   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   )r=   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: %s)r   )r=   r   r   r   r   r   r   /  s    zSignalWatcher.on_printer_addedc             C   s   t d|||f  d S )Nz*%s: printer event: %s: %s)r   )r=   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 removed)r   )r=   r   r   r   r   r   r   5  s    z SignalWatcher.on_printer_removedc             C   s   t d|  d S )Nz*%s: cups connection error)r   )r=   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): %s)r   )r=   r   errZ	errstringr   r   r   r   ;  s    zSignalWatcher.on_cups_ipp_errorN)r   r   r   r#   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s   r   T) configr   Zrequirer6   Z	dbus.glibZgi.repositoryr   r   rU   debugrj   gettextinstallZPACKAGEr   r   Zstatereasonr   r[   r   r   r   r   r   r   Zset_debuggingr|   r   ZMainLoopZloopZrunrL   r   r   r   r   <module>   sD   
	     F
9