U
    hk                     @   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-ehb4gh6l/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   