
    R1gV              	          U d 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Zddl	m
Z
mZmZmZmZmZmZ ddlmZ 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"m#Z#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/  e
de0dd      Z1 G d d      Z2 e2       Z3e2e4d<   d Z5e1jl                  d        Z7d Z8d Z9d Z:d Z;de fdZ<d  Z=d! Z>dPd"Z?e1j                  d#      d$        ZAd% ZBd& ZCe1j                  d'd(di)      e1j                  d*      e1j                  d+      e1j                  d,      d-                             ZDe1j                  d.      d/        ZEe1j                  d0dd1d2d3d4d5)      e1j                  d6      d7               ZFe1j                  d8      d9        ZGe1j                  d:d;g<      e9e8dQd=                     ZHe1j                  d>d;g<      e8d?               ZIe1j                  d@dAd;g<      e8dB               ZJe1j                  dCd;g<      e9e8dD                      ZKe1j                  dEd;g<      e8dF               ZLe1j                  dG      e8dH               ZMe1j                  dI      e8dJ               ZNe1j                  dK      e8dL               ZOe1j                  dM      e8dN               ZPe1j                  dO        ZRy)Ra  RQ Dashboard Flask Blueprint.

Uses the standard Flask configuration mechanism e.g. to set the connection
parameters to REDIS. To keep the documentation and defaults all in once place
the default settings must be loaded from ``rq_dashboard.default_settings``
e.g.  as done in ``cli.py``.

RQ Dashboard does not contain any built-in authentication mechanism because

    1. it is the responsbility of the wider hosting app rather than a
       particular blueprint, and

    2. there are numerous ways of adding security orthogonally.

As a quick-and-dirty convenience, the command line invocation in ``cli.py``
provides the option to require HTTP Basic Auth in a few lines of code.

    Nwraps)ceil)	Blueprintcurrent_appmake_responserender_templaterequestsend_from_directoryurl_for)ConnectionError)connect)VERSIONQueueWorkerrequeue_job)NoSuchJobError)Job)DeferredJobRegistryFailedJobRegistryFinishedJobRegistryStartedJobRegistryScheduledJobRegistryCanceledJobRegistry)string_types   )upgrade_config)r   )DefaultSerializerrq_dashboard	templatesstatic)template_folderstatic_folderc                       e Zd ZeZy)ConfigN)__name__
__module____qualname__r   
serializer     j/var/www/trellinator.diamondhoofcare.com/public_html/venv/lib/python3.12/site-packages/rq_dashboard/web.pyr%   r%   B   s    "Jr+   r%   configc                 .   t        |        | j                  j                  d      }t        |t              r(|f| j                  d<   t        |fd         \  }| _        y t        |t        t        f      rt        |d         \  }| _        y t        d      )NRQ_DASHBOARD_REDIS_URLr   zNo Redis configuration!)
r   r-   get
isinstancer   from_url
redis_conntuplelistRuntimeError)r   	redis_url_s      r,   setup_rq_connectionr9   H   s    ;""&&'?@I)\*8A|34$,i\!_$=!;!	It}	-$,Yq\$:!;!455r+   c                  &   t         j                  j                  d      } | Ut        j                  j                  d      }| t        |      k  rt        ||          \  }}|t        _        y t        d      t        j                  }|t        _        y )Ninstance_numberr/   z%Index exceeds RQ list. Not Permitted.)	r
   	view_argsr0   r   r-   lenr2   LookupErrorr3   )new_instance_numberr7   r8   new_instances       r,   push_rq_connectionrA   V   s    !++//0AB&&&**+CD	Y/&y1D'EFOA| *K	 EFF"--)Kr+   c                 .     t                fd       }|S )Nc                  8    ddl m}  | i |} |di |ddifS )Nr   )jsonifyCache-Controlno-storer*   )flaskrD   )argskwargsflask_jsonifyresult_dictfs       r,   _wrappedzjsonify.<locals>._wrappedi   s-    2((+{+oz-JJJr+   r   )rL   rM   s   ` r,   rD   rD   h   s"    
1XK K Or+   c                 .     t                fd       }|S )Nc                  j    t         j                  j                  d      rt        d      S  | i |S )NRQ_DASHBOARD_DISABLE_DELETEDISABLEDstatusr   r-   r0   dict)rH   rI   rL   s     r,   wrapperz$check_delete_enable.<locals>.wrappers   s3    !!"?@z**$!&!!r+   r   )rL   rV   s   ` r,   check_delete_enablerW   r   s     
1X" " Nr+   c                    |D cg c]  }t        |j                  |j                  t        d| |j                  dddd      t	        |j                  |j
                        j                  t        d| |j                  dddd      t        |j                  |j
                        j                  t        d| |j                  d	ddd      t        |j                  |j
                        j                  t        d| |j                  d
ddd      t        |j                  |j
                        j                  t        d| |j                  dddd      t        |j                  |j
                        j                  t        d| |j                  dddd      t        |j                  |j
                        j                  t        d| |j                  dddd             c}S c c}w )N.jobs_overviewqueued8asc1r;   
queue_nameregistry_nameper_pageorderpage
connectionfailedstarteddeferredfinishedcanceled	scheduled)namecount
queued_urlfailed_job_registry_count
failed_urlstarted_job_registry_countstarted_urldeferred_job_registry_countdeferred_urlfinished_job_registry_countfinished_urlcanceled_job_registry_countcanceled_urlscheduled_job_registry_countscheduled_url)rU   rl   rm   r   r   re   r   r   r   r   r   )r;   queuesqs      r,   serialize_queuesr}   z   s   V UKT S 	''  /66& '81<<&X&^&^  /66& (:!&&Q\\'Z'`'`  /66' )<AFFq||(\(b(b   /66( )<AFFq||(\(b(b   /66( )<AFFq||(\(b(b   /66( *>affQRQ]Q])^)d)d!  /66)H	
K K Ks   G#G+c                     | y t        j                  |       j                  d      j                  j	                         S )NUTC)arrowr0   todatetime	isoformat)dts    r,   serialize_dater      s2    	z99R=E"++5577r+   jobc                     | j                         }t        | j                  t        | j                        t        | j
                        |r|j                  nd | j                        S )N)id
created_atended_atexc_infodescription)latest_resultrU   r   r   r   r   
exc_stringr   )r   r   s     r,   serialize_jobr      sP    %%'M66!#..1--:))OO r+   c                     | yt        | j                  | j                  t        | j                        | j                               S )Nidle)job_idr   r   call_string)rU   r   r   r   r   get_call_string)r   s    r,   serialize_current_jobr      s=    
{vvOO!#..1'')	 r+   c                 B    t        d | j                         D              S )Nc              3   0   K   | ]  \  }}|	||f  y wNr*   ).0kvs      r,   	<genexpr>z%remove_none_values.<locals>.<genexpr>   s     HDAq!-!QHs   
	)rU   items)
input_dicts    r,   remove_none_valuesr      s    HJ$4$4$6HIIr+   c                     t        dt        t        | t        |      z              dz         }|}|dk\  rIt	        t        |      |z
  |dz
  t        t        |dz              z
        }t        d|      }||z   }||| }|S )Nr   g       @r   )rangeintr   floatminr=   max)	total_itemscur_pagera   window_size	all_pagesresulttemppages_window_startpages_window_ends	            r,   pagination_windowr      s    aT+h"?@AAEFIFa	N[(8a<3tKRUDU?V;W*W
 !D\-;-.>?Mr+   z/favicon.icoc                  v    t        t        j                  j                  t        j
                  d      dd      S )Nr!   zfavicon.icozimage/vnd.microsoft.icon)mimetype)r   ospathjoin	blueprint	root_pathr*   r+   r,   faviconr      s-    
Y(((3+ r+   c                 |   t        | t        j                  |      }|dk7  r|dk\  r||dz
  z   }|dk(  rt        | |      }na|dk(  rt	        | |      }nN|dk(  rt        | |      }n;|d	k(  rt        | |      }n(|d
k(  rt        | |      }n|dk(  rt        | |      }n|}j                  }|dk(  r||z
  }	t        d|	|z
        }
n|}
|
|z   }	|j                  |
|	      }|dk(  r|j                          |D cg c]  }|j                  |       }}|D cg c]  }|st        |       }}||fS c c}w c c}w )Nr)   re   rZ   r   r   rf   rd   rh   rg   ri   rk   rj   dsc)r   r-   r)   r   r   r   r   r   r   rm   r   get_job_idsreverse	fetch_jobr   )r_   r`   offsetra   rb   re   queuecurrent_queuer   endstartjob_idsr   current_queue_jobsr   jobss                   r,   get_queue_registry_jobs_countr      s[   *):):zRE q=A.HH$-jZPMj(/
zRMi'.zjQMj(/
zRMk)0
SMj(/
zRM%%K ~F"AsX~&h''s3G~@GHf%//&1HH*<D3M#DDD IDs   ;D4D9!D9c                     t        | t        t        f      r&| D cg c]  }t        j                  dd|       } }| S t        | t
              rt        j                  dd|       g} | S c c}w )Nz:\/\/[^@]*@z://***:***@)r1   r5   r4   resubr   )url_listxs     r,   escape_format_instance_listr   '  sc    (T5M*FNOBFF>=!<OO O 
Hl	+FF>=(CDO Ps   A'/r;   )defaultsz/<int:instance_number>/z/<int:instance_number>/viewz"/<int:instance_number>/view/queuesc                    	 t        t        d| t        t        j                  j                  d            t        j                  t        j                        t        d      t        t        dt        j                  j                  dd      	            }|j                  j                  d
d       |S # t        $ r t        d	      }Y 4w xY w)Nzrq_dashboard/queues.htmlr/   rd   .queues_overviewr{   DEPRECATED_OPTIONSF)current_instanceinstance_listr{   rq_url_prefixrq_dashboard_version
rq_version
active_tabdeprecation_options_usagez<h1>Connection Error</h1>rE   rF   )r   r	   r   r   r-   r0   r   allr3   r   r   r   RedisConnectionErrorheaderssetr;   rs     r,   queues_overviewr   /  s    

*!09+:L:L:P:PQi:jkyyK,B,BC%&89%9%#*5*<*<*@*@(%+
& IIMM/:.H   
'

s   BB4 4C
Cz#/<int:instance_number>/view/workersc                 f   t        t        d| t        t        j                  j                  d            t        j                  t        j                        t        d      t        t        dt        j                  j                  dd      	            }|j                  j                  d	d
       |S )Nzrq_dashboard/workers.htmlr/   rd   r   workersr   F)r   r   r   r   r   r   r   r   rE   rF   )r   r	   r   r   r-   r0   r   r   r3   r   r   r   r   r   r   s     r,   workers_overviewr   L  s    ',5k6H6H6L6LMe6fgJJ+*@*@A!"45!5! &1&8&8&<&<$e'	
	A IIMM/:.Hr+   z /<int:instance_number>/view/jobsrZ   r[   r\   r]   )r_   r`   ra   rb   rc   z_/<int:instance_number>/view/jobs/<queue_name>/<registry_name>/<int:per_page>/<order>/<int:page>c                 Z   |*t        t        j                  t        j                        }n*t        |t        j                  t        j                        }t        t        d| t        t        j                  j                  d            t        j                  t        j                        |||||t        d      t        t        dt        j                  j                  dd      t        j                  j                  d	       
            }|j                  j                  dd       |S )Nr   zrq_dashboard/jobs.htmlr/   rd   r   r   r   FrP   )r   r   r{   r   ra   rb   rc   r`   r   r   r   r   r   enable_deleterE   rF   )r   r-   r)   r   r3   r   r	   r   r0   r   r   r   r   r   r   )r;   r_   r`   ra   rb   rc   r   r   s           r,   jobs_overviewr   a  s     !2!2{?U?UVjV->->;KaKab$,5k6H6H6L6LMe6fg99(>(>?'!"45!5!&1&8&8&<&<$e' *00445RSS#	
	A* IIMM/:.Hr+   z(/<int:instance_number>/view/job/<job_id>c                    t        j                  |t        j                        }t	        t        d| t        t        j                  j                  d            |j                  t        d      t        t        t        j                  j                  dd      t        j                  j                  d       	            }|j                  j                  d	d
       |S )Nrd   zrq_dashboard/job.htmlr/   r   r   FrP   )r   r   r   r   r   r   r   r   rE   rF   )r   fetchr   r3   r   r	   r   r-   r0   r   r   r   r   r   r   )r;   r   r   r   s       r,   job_viewr     s    
))F{'='=
>C#,5k6H6H6L6LMe6fgvv!"45!5!&1&8&8&<&<$e' *00445RSS	
	A IIMM/:.Hr+   z/job/<job_id>/deletePOST)methodsc                     	 t        j                  | t        j                        }|j	                          t        d      S # t
        $ r" |r|j                  |        t        d      cY S w xY w)Nrd   ERRORrR   OK)r   r   r   r3   deleter   removerU   )r   registryr   s      r,   delete_job_viewr     s^    $ii;+A+AB

 t  $OOF#7##$s   5A (A.-A.z/job/<job_id>/requeuec                 P    t        | t        j                         t        d      S )Nrd   r   rR   )r   r   r3   rU   )r   s    r,   requeue_job_viewr     s     ;#9#9:tr+   z/requeue/<queue_name>GETc                     t        | t        j                  t        j                        j
                  }|j                         }t        |      }|D ]  }t        |t        j                          t        d|      S )Nr   rd   r   )rS   rm   )
r   r-   r)   r   r3   failed_job_registryr   r=   r   rU   )r_   fqr   rm   r   s        r,   requeue_allr     se     
zf&7&7KDZDZ	[	o	oBnnGLE ?F{'='=>?t5))r+   z)/queue/<queue_name>/<registry_name>/emptyc                    |dk(  r<t        | t        j                  t        j                        }|j                          n|dk(  r>t        | t        j                        }|j                         D ]  }t        ||        nJ|dk(  r>t        | t        j                        }|j                         D ]  }t        ||        n|dk(  r=t        | t        j                        }|j                         D ]  }t        ||        n|dk(  r=t        | t        j                        }|j                         D ]  }t        ||        n|dk(  r=t        | t        j                        }|j                         D ]  }t        ||        nA|d	k(  r<t        | t        j                        }|j                         D ]  }t        ||        t        d
      S )NrZ   r   rf   rd   rh   rg   ri   rj   rk   r   rR   )r   r-   r)   r   r3   emptyr   r   r   r   r   r   r   r   rU   )r_   r`   r|   r   r   s        r,   empty_queuer     s     *):):{G]G]^			(	"$ZK<R<RS&&( 	*BB)	*	*	$&zk>T>TU&&( 	*BB)	*	)	#%j[=S=ST&&( 	*BB)	*	*	$&zk>T>TU&&( 	*BB)	*	*	$&zk>T>TU&&( 	*BB)	*	+	%'
{?U?UV&&( 	*BB)	* tr+   z/queue/<queue_name>/compactc                     t        | t        j                  t        j                        }|j                          t        d      S )Nr   r   rR   )r   r-   r)   r   r3   compactrU   )r_   r|   s     r,   compact_queuer     s2     	jV%6%6;CYCYZAIIKtr+   z'/<int:instance_number>/data/queues.jsonc                     t        | t        t        j                  t        j
                                    }t        |      S )Nrd   )r{   )r}   sortedr   r   r   r3   rU   )r;   r{   s     r,   list_queuesr     s/     oveii;KaKa6b/cdFvr+   z\/<int:instance_number>/data/jobs/<queue_name>/<registry_name>/<per_page>/<order>/<page>.jsonc                    t        |      }t        |      }|dz
  |z  }t        |||||t        j                        \  }}	t	        |||      }
|
D cg c]  }t        |t        d| |||||            ! }}t        t        |t        |      z              }d }|dkD  rt        t        d| |||||dz
              }d }||k  rt        t        d| |||||dz               }t        t        d| ||||d            }t        t        d| |||||            }t        t        |||||||            }t        |||	|      S c c}w )Nr   rY   r^   )numberurl)r  )current_page	num_pagespages_in_window	next_page	prev_page
first_page	last_page)rl   r`   r   
pagination)
r   r   r   r3   r   rU   r   r   r   r   )r;   r_   r`   ra   rb   rc   r  r   r   r   pages_numbers_in_windowpr  r
  r  r  first_page_linklast_page_linkr  s                      r,   	list_jobsr    s   
 t9L8}HQ(*F5M68UK<R<RK 0\8T )  	  /%+!	
O  DuX678IIa  /%+!"Q&

	 Ii  /%+!"Q&

	 +!'

O +!'

N $%+&$	

J }4J as   $Ez-/<int:instance_number>/data/job/<job_id>.jsonc                    t        j                  |t        j                  t        j
                        }|j                         }t        |j                  t        |j                        t        |j                        t        |j                        |j                  |j                         |j                         |r|j                   nd |j"                  t%        j&                  |j)                               
      }|j*                  D cg c]3  }|j-                  d      j/                  d      d   j1                         5 }}t3        |      dkD  rJ||d<   g }|D ]9  }	 t        j                  |t        j                        }	|j5                  d	       ; ||d<   |S c c}w # t6        $ r |j5                  d
       Y dw xY w)Nr   )
r   r   enqueued_atr   originrS   r   r   r   metadatazutf-8:r   
depends_on)r)   activeexpireddepends_on_status)r   r   r-   r)   r   r3   r   rU   r   r   r   r  r   r  
get_statusreturn_valuer   r   jsondumpsget_metadependency_idsdecodesplitstripr=   appendr   )
r;   r   r   r   r   didep_idsrS   dep_idr8   s
             r,   job_infor(  X  sm    ))Fv'8'8[E[E[
\C%%'M66!#..1"3??3-zz~~!-:))OOCLLN+F DGCUCUVRryy!'',R0668VGV
7|a&| 	)F)IIf1B1BCh'	) '-"#M W " )i()s   
8F6F##G ?G z(/<int:instance_number>/data/workers.jsonc                     d t        fdt        j                  t        j                        D        d       }t        |      S )Nc                 T    | j                   D cg c]  }|j                   c}S c c}w r   )r{   rl   )workerr|   s     r,   serialize_queue_namesz+list_workers.<locals>.serialize_queue_namesz  s     &.1...s   %c              3   l  K   | ]  }t        |j                  |j                   |      t        |j	                               t        |j                               |j                  |j                  |j                  |j                  |j                  t        |d d      t        |dd              yw)version python_version)rl   pidr{   statecurrent_joblast_heartbeat
birth_datesuccessful_job_countfailed_job_counttotal_working_timer.  r0  N)rU   rl   r1  str	get_stater   get_current_jobr4  r5  r6  r7  r8  getattr)r   r+  r,  s     r,   r   zlist_workers.<locals>.<genexpr>~  s      	
  [[JJ,V4&**,-1&2H2H2JK%44!,,%+%@%@!'!8!8#)#<#<	26&v/?D 	
s   B1B4rd   c                     | d   | d   | d   fS )Nr2  r{   rl   r*   )ws    r,   <lambda>zlist_workers.<locals>.<lambda>  s    qz1X;&	: r+   )key)r   )r   r   r   r   r3   rU   )r;   r   r,  s     @r,   list_workersrA  w  sD    / 	
 !**0F0FG	
" ;%G(   r+   c                  Z    t         j                  j                  dd      } t        |       S )NRQ_DASHBOARD_POLL_INTERVALi	  )poll_intervalrT   )intervals    r,   inject_intervalrF    s&    !!%%&BDIHh''r+   )
   r   )S__doc__r  r   r   	functoolsr   mathr   r   rG   r   r   r   r	   r
   r   r   redis.exceptionsr   r   redis_sentinel_urlr   r2   rqr   r   r   r   r   rq.exceptionsr   rq.jobr   rq.registryr   r   r   r   r   r   sixr   legacy_configr   r.  r   rq.serializersr   r&   r   r%   r-   __annotations__r9   before_requestrA   rD   rW   r}   r   r   r   r   r   router   r   r   r   r   r   r   r   r   r   r   r   r   r  r(  rA  context_processorrF  r*   r+   r,   <module>rX     s  $  	 	      E 2  )    ) 4 , Hk	# #  6 * *"L^8s J
   !%P  1156
*+
./
56 7 0 , 72 67 8( &!  	 e	< ;< =* '&:	 	  ;	 (6(; 	 <
 (5&/B* 	 C* <vhO 	  P@ .A 	 B :; 	 <
 b 	\ 	\~ @A 	 B: ;<! 	 =!6 ( (r+   