o
    wvXj†,  ã                   @   s  d Z ddlmZmZ ddlmZmZ ddlmZ ddlm	Z	 ddl
mZmZ ddlmZ ddlmZ dd	lmZmZ d
dlmZ zddlZW n eyQ   dZY nw erszddlmZ W n eyk   ddlmZ Y nw ddlmZ n
dZG dd„ deƒZdZeddgƒZ G dd„ deƒZ!dS )zMongoDB result store backend.é    )Úabsolute_importÚunicode_literals)ÚdatetimeÚ	timedelta)ÚEncodeError)Úcached_property)Úmaybe_sanitize_urlÚurlparse)Ústates)ÚImproperlyConfigured)ÚitemsÚstring_té   )ÚBaseBackendN)ÚBinary)ÚInvalidDocumentc                   @   s   e Zd ZdS )r   N)Ú__name__Ú
__module__Ú__qualname__© r   r   úT/var/www/html/myproject/venv/lib/python3.10/site-packages/celery/backends/mongodb.pyr      s    r   )ÚMongoBackendÚpickleÚmsgpackc                       s  e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZdZd	ZdZd3‡ fd
d„	Zedd„ ƒZdd„ Zdd„ Z‡ fdd„Z‡ fdd„Z	d4dd„Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd5‡ fd%d&„	Zd'd(„ Ze d)d*„ ƒZ!e d+d,„ ƒZ"e d-d.„ ƒZ#e d/d0„ ƒZ$d6d1d2„Z%‡  Z&S )7r   z‘MongoDB result backend.

    Raises:
        celery.exceptions.ImproperlyConfigured:
            if module :pypi:`pymongo` is not available.
    NÚ	localhosti‰i  ÚceleryÚcelery_taskmetaÚcelery_groupmetaé
   Fc                    s¬  i | _ tt| ƒj|fi |¤Ž tstdƒ‚t|  ¡ ƒD ]\}}| j  ||¡ q| j	r_|  
| j	¡| _	tj | j	¡}dd„ |d D ƒ}|d | _|d | _|| _|d rW|d | _| j  |d ¡ | jj d	¡}|d urÔt|tƒsstd
ƒ‚t|ƒ}d|v sd|v r‚d | _| d| j¡| _| d| j¡| _| d| j¡| _| d| j¡| _| d| j¡| _| d| j¡| _| d| j¡| _| d| j¡| _| j  | di ¡¡ | j  |¡ d S d S )NzCYou need to install the pymongo library to use the MongoDB backend.c                 S   s    g | ]}d   |d |d ¡‘qS )z{0}:{1}r   r   )Úformat)Ú.0Úxr   r   r   Ú
<listcomp>R   s    ÿz)MongoBackend.__init__.<locals>.<listcomp>ÚnodelistÚusernameÚpasswordÚdatabaseÚoptionsÚmongodb_backend_settingsz4MongoDB backend settings should be grouped in a dictÚhostÚportÚ
mongo_hostÚuserÚtaskmeta_collectionÚgroupmeta_collection)r'   Úsuperr   Ú__init__Úpymongor   r   Ú_prepare_client_optionsÚ
setdefaultÚurlÚ_ensure_mongodb_uri_complianceÚ
uri_parserÚ	parse_urir,   r%   r+   Údatabase_nameÚupdateÚappÚconfÚgetÚ
isinstanceÚdictÚpopr)   r*   r-   r.   )Úselfr:   ÚkwargsÚkeyÚvalueÚuri_dataÚ	hostslistÚconfig©Ú	__class__r   r   r0   >   sX   ÿÿ



ÿÿÿèzMongoBackend.__init__c                 C   s2   t | ƒ}|j d¡sd | ¡} | dkr| d7 } | S )NÚmongodbz
mongodb+{}ú
mongodb://r   )r	   ÚschemeÚ
startswithr   )r4   Ú
parsed_urlr   r   r   r5   z   s   
z+MongoBackend._ensure_mongodb_uri_compliancec                 C   s    t jdkr
d| jiS | jddœS )N)é   ÚmaxPoolSizeF)Úmax_pool_sizeÚauto_start_request)r1   Úversion_tuplerP   ©r@   r   r   r   r2   …   s
   

ÿz$MongoBackend._prepare_client_optionsc                 C   s�   | j du rEddlm} | j}|s$| j}t|tƒr$| d¡s$d || j	¡}t
| jƒ}||d< | jr5| j|d< | jr=| j|d< |d	i |¤Ž| _ | j S )
zConnect to the MongoDB server.Nr   )ÚMongoClientrJ   zmongodb://{0}:{1}r)   r$   r%   r   )Ú_connectionr1   rT   r+   r)   r=   r   rL   r   r*   r>   r'   r,   r%   )r@   rT   r)   r;   r   r   r   Ú_get_connectionŒ   s"   

ÿ


zMongoBackend._get_connectionc                    s4   | j dkr|S tt| ƒ |¡}| j tv rt|ƒ}|S ©NÚbson)Ú
serializerr/   r   ÚencodeÚBINARY_CODECSr   ©r@   ÚdataÚpayloadrG   r   r   rZ   ©   s   

zMongoBackend.encodec                    s(   | j dkr|S |  |¡}tt| ƒ |¡S rW   )rY   rZ   r/   r   Údecoder\   rG   r   r   r_   ´   s   

zMongoBackend.decodec           	   
   K   sX   | j ||||d�}||d< z| jjd|i|dd� W |S  ty+ } zt|ƒ‚d}~ww )z1Store return value and state of an executed task.)ÚresultÚstateÚ	tracebackÚrequestÚ_idT©ÚupsertN)Ú_get_result_metaÚ
collectionÚreplace_oner   r   )	r@   Útask_idr`   ra   rb   rc   rA   ÚmetaÚexcr   r   r   Ú_store_result»   s   ÿý€ÿzMongoBackend._store_resultc                 C   sb   | j  d|i¡}|r+|  |d |d |  |d ¡|d |  |d ¡|  |d ¡dœ¡S tjdd	œS )
z$Get task meta-data for a task by id.rd   Ústatusr`   Ú	date_donerb   Úchildren)rj   rn   r`   ro   rb   rp   N)rn   r`   )rh   Úfind_oneÚmeta_from_decodedr_   r
   ÚPENDING)r@   rj   Úobjr   r   r   Ú_get_task_meta_forÊ   s   úzMongoBackend._get_task_meta_forc                 C   s:   ||   dd„ |D ƒ¡t ¡ dœ}| jjd|i|dd� |S )zSave the group result.c                 S   s   g | ]}|j ‘qS r   )Úid)r    Úir   r   r   r"   Ü   s    z,MongoBackend._save_group.<locals>.<listcomp>)rd   r`   ro   rd   Tre   )rZ   r   ÚutcnowÚgroup_collectionri   )r@   Úgroup_idr`   rk   r   r   r   Ú_save_groupØ   s   ýzMongoBackend._save_groupc                    sD   ˆ j  d|i¡}|r |d |d ‡ fdd„ˆ  |d ¡D ƒdœS dS )z!Get the result for a group by id.rd   ro   c                    s   g | ]}ˆ j  |¡‘qS r   )r:   ÚAsyncResult)r    ÚtaskrS   r   r   r"   é   s    
ÿÿz/MongoBackend._restore_group.<locals>.<listcomp>r`   )rj   ro   r`   N)ry   rq   r_   )r@   rz   rt   r   rS   r   Ú_restore_groupâ   s   
þýÿzMongoBackend._restore_groupc                 C   ó   | j  d|i¡ dS )zDelete a group by id.rd   N)ry   Ú
delete_one)r@   rz   r   r   r   Ú_delete_groupï   s   zMongoBackend._delete_groupc                 C   r   )zšRemove result from MongoDB.

        Raises:
            pymongo.exceptions.OperationsError:
                if the task_id could not be removed.
        rd   N)rh   r€   )r@   rj   r   r   r   Ú_forgetó   s   
zMongoBackend._forgetc                 C   sD   | j  dd| j ¡ | j ii¡ | j dd| j ¡ | j ii¡ dS )zDelete expired meta-data.ro   z$ltN)rh   Údelete_manyr:   ÚnowÚexpires_deltary   rS   r   r   r   Úcleanupÿ   s   ÿÿzMongoBackend.cleanupr   c                    s,   |si n|}t t| ƒ |t|| j| jd�¡S )N)Úexpiresr4   )r/   r   Ú
__reduce__r>   r‡   r4   )r@   ÚargsrA   rG   r   r   rˆ     s   
ÿzMongoBackend.__reduce__c                 C   sR   |   ¡ }|| j }| jr'| jr'| j d| jpd¡}|j| j| j|d�s'tdƒ‚|S )NÚ
authsourceÚadmin)Úsourcez%Invalid MongoDB username or password.)rV   r8   r,   r%   r'   r<   Úauthenticater   )r@   ÚconnÚdbrŒ   r   r   r   Ú_get_database  s   
þÿzMongoBackend._get_databasec                 C   s   |   ¡ S )z]Get database from MongoDB connection.

        performs authentication if necessary.
        )r�   rS   r   r   r   r&     s   zMongoBackend.databasec                 C   ó   | j | j }|jddd� |S ©z"Get the meta-data task collection.ro   T)Ú
background)r&   r-   Úcreate_index©r@   rh   r   r   r   rh   "  ó   zMongoBackend.collectionc                 C   r‘   r’   )r&   r.   r”   r•   r   r   r   ry   ,  r–   zMongoBackend.group_collectionc                 C   s   t | jd�S )N)Úseconds)r   r‡   rS   r   r   r   r…   6  s   zMongoBackend.expires_deltac                 C   sL   | j sdS |r
| j S d| j vrt| j ƒS | j  dd¡\}}d t|ƒ|g¡S )z~Return the backend as an URI.

        Arguments:
            include_password (bool): Password censored if disabled.
        rJ   ú,r   )r4   r   ÚsplitÚjoin)r@   Úinclude_passwordÚuri1Ú	remainderr   r   r   Úas_uri:  s   

zMongoBackend.as_uri)N)NN)r   N)F)'r   r   r   Ú__doc__r+   r)   r*   r,   r%   r8   r-   r.   rP   r'   Úsupports_autoexpirerU   r0   Ústaticmethodr5   r2   rV   rZ   r_   rm   ru   r{   r~   r�   r‚   r†   rˆ   r�   r   r&   rh   ry   r…   rž   Ú__classcell__r   r   rG   r   r   '   sP    <


ÿ
	

	
	
r   )"rŸ   Ú
__future__r   r   r   r   Úkombu.exceptionsr   Úkombu.utils.objectsr   Úkombu.utils.urlr   r	   r   r
   Úcelery.exceptionsr   Úcelery.fiver   r   Úbaser   r1   ÚImportErrorÚbson.binaryr   Úpymongo.binaryÚpymongo.errorsr   Ú	ExceptionÚ__all__Ú	frozensetr[   r   r   r   r   r   Ú<module>   s6   ÿÿ