U
    Šfjk  ã                   @   sÈ   d dl mZ d dlmZ d dlmZ d dlZd dlmZmZm	Z	 d dl
mZmZ d dlmZ zd dlZW n ek
r„   d dlZY nX zd dlmZ W n ek
r²   ed	ƒ‚Y nX G d
d„ deƒZdS )é    )Úabsolute_import)Údatetime)ÚutcN)ÚBaseJobStoreÚJobLookupErrorÚConflictingIdError)Údatetime_to_utc_timestampÚutc_timestamp_to_datetime)ÚJob)ÚRedisz&RedisJobStore requires redis installedc                       sŒ   e Zd ZdZdddejf‡ f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‡  ZS )ÚRedisJobStoreaË  
    Stores jobs in a Redis database. Any leftover keyword arguments are directly passed to redis's
    :class:`~redis.StrictRedis`.

    Plugin alias: ``redis``

    :param int db: the database number to store jobs in
    :param str jobs_key: key to store jobs in
    :param str run_times_key: key to store the jobs' run times in
    :param int pickle_protocol: pickle protocol level to use (for serialization), defaults to the
        highest available
    r   zapscheduler.jobszapscheduler.run_timesc                    sd   t t| ƒ ¡  |d krtdƒ‚|s*tdƒ‚|s6tdƒ‚|| _|| _|| _tf dt|ƒi|—Ž| _	d S )Nz$The "db" parameter must not be emptyz*The "jobs_key" parameter must not be emptyz/The "run_times_key" parameter must not be emptyÚdb)
Úsuperr   Ú__init__Ú
ValueErrorÚpickle_protocolÚjobs_keyÚrun_times_keyr   ÚintÚredis)Úselfr   r   r   r   Zconnect_args©Ú	__class__© ú?/tmp/pip-unpacked-wheel-3wcy9vrk/apscheduler/jobstores/redis.pyr   $   s    zRedisJobStore.__init__c                 C   s"   | j  | j|¡}|r|  |¡S d S ©N)r   Zhgetr   Ú_reconstitute_job)r   Újob_idÚ	job_stater   r   r   Ú
lookup_job4   s    zRedisJobStore.lookup_jobc                 C   sJ   t |ƒ}| j | jd|¡}|rF| jj| jf|žŽ }|  tj 	||¡¡S g S )Nr   )
r   r   Zzrangebyscorer   Zhmgetr   Ú_reconstitute_jobsÚsixÚmovesÚzip)r   ÚnowÚ	timestampZjob_idsÚ
job_statesr   r   r   Úget_due_jobs8   s    zRedisJobStore.get_due_jobsc                 C   s.   | j j| jdddd�}|r*t|d d ƒS d S )Nr   T)Z
withscoresé   )r   Zzranger   r	   )r   Únext_run_timer   r   r   Úget_next_run_time@   s    zRedisJobStore.get_next_run_timec                    sB   | j  | j¡}|  t |¡¡}tdddtd�‰ t|‡ fdd„d�S )Ni'  é   é   )Útzinfoc                    s
   | j pˆ S r   )r)   )Újob©Zpaused_sort_keyr   r   Ú<lambda>I   ó    z,RedisJobStore.get_all_jobs.<locals>.<lambda>)Úkey)	r   Zhgetallr   r    r!   Ú	iteritemsr   r   Úsorted)r   r&   Újobsr   r/   r   Úget_all_jobsE   s    zRedisJobStore.get_all_jobsc              	   C   s†   | j  | j|j¡rt|jƒ‚| j  ¡ �V}| ¡  | | j|jt 	| 
¡ | j¡¡ |jrp| | j|jt|jƒi¡ | ¡  W 5 Q R X d S r   )r   Úhexistsr   Úidr   ÚpipelineZmultiÚhsetÚpickleÚdumpsÚ__getstate__r   r)   Úzaddr   r   Úexecute©r   r.   Úpiper   r   r   Úadd_jobK   s    
ÿÿzRedisJobStore.add_jobc              	   C   s�   | j  | j|j¡st|jƒ‚| j  ¡ �`}| | j|jt | 	¡ | j
¡¡ |jrj| | j|jt|jƒi¡ n| | j|j¡ | ¡  W 5 Q R X d S r   )r   r7   r   r8   r   r9   r:   r;   r<   r=   r   r)   r>   r   r   Úzremr?   r@   r   r   r   Ú
update_jobY   s    
ÿÿzRedisJobStore.update_jobc              	   C   sV   | j  | j|¡st|ƒ‚| j  ¡ �*}| | j|¡ | | j|¡ | ¡  W 5 Q R X d S r   )	r   r7   r   r   r9   ÚhdelrC   r   r?   )r   r   rA   r   r   r   Ú
remove_jobh   s    zRedisJobStore.remove_jobc              	   C   s:   | j  ¡ �&}| | j¡ | | j¡ | ¡  W 5 Q R X d S r   )r   r9   Údeleter   r   r?   )r   rA   r   r   r   Úremove_all_jobsq   s    zRedisJobStore.remove_all_jobsc                 C   s   | j j ¡  d S r   )r   Zconnection_poolZ
disconnect©r   r   r   r   Úshutdownw   s    zRedisJobStore.shutdownc                 C   s2   t  |¡}t t¡}| |¡ | j|_| j|_|S r   )r;   Úloadsr
   Ú__new__Ú__setstate__Z
_schedulerÚ_aliasZ_jobstore_alias)r   r   r.   r   r   r   r   z   s    


zRedisJobStore._reconstitute_jobc              	   C   s¢   g }g }|D ]J\}}z|  |  |¡¡ W q tk
rT   | j d|¡ |  |¡ Y qX q|rž| j ¡ �2}|j| jf|žŽ  |j	| j
f|žŽ  | ¡  W 5 Q R X |S )Nz)Unable to restore job "%s" -- removing it)Úappendr   ÚBaseExceptionZ_loggerÚ	exceptionr   r9   rE   r   rC   r   r?   )r   r&   r5   Zfailed_job_idsr   r   rA   r   r   r   r    ‚   s    z RedisJobStore._reconstitute_jobsc                 C   s   d| j j S )Nz<%s>)r   Ú__name__rI   r   r   r   Ú__repr__•   s    zRedisJobStore.__repr__)rR   Ú
__module__Ú__qualname__Ú__doc__r;   ÚHIGHEST_PROTOCOLr   r   r'   r*   r6   rB   rD   rF   rH   rJ   r   r    rS   Ú__classcell__r   r   r   r   r      s    ÿ	r   )Ú
__future__r   r   Zpytzr   r!   Zapscheduler.jobstores.baser   r   r   Zapscheduler.utilr   r	   Zapscheduler.jobr
   ÚcPickler;   ÚImportErrorr   r   r   r   r   r   r   Ú<module>   s   