
    ej_$                     x    d Z ddlZddlZddlZddlZddlmZmZ ddl	m
Z
 d Zd Zd Zd Z G d	 d
          ZdS )zServe GridFS files with Motor and aiohttp.

Requires Python 3.5 or later and aiohttp 3.0 or later.

See the :doc:`/examples/aiohttp_gridfs_example`.
    N)AsyncIOMotorDatabaseAsyncIOMotorGridFSBucket)_hash_gridoutc                 ,    |                      |          S )a&  Override to choose a GridFS file to serve at a URL.

    By default, if a URL pattern like ``/fs/{filename}`` is mapped to this
    :class:`AIOHTTPGridFS`, then the filename portion of the URL is used as the
    filename, so a request for "/fs/image.png" results in a call to
    :meth:`.AsyncIOMotorGridFSBucket.open_download_stream_by_name` with
    "image.png" as the ``filename`` argument. To customize the mapping of path
    to GridFS file, override ``get_gridfs_file`` and return a
    :class:`asyncio.Future` that resolves to a
    :class:`~motor.motor_asyncio.AsyncIOMotorGridOut`.

    For example, to retrieve the file by ``_id`` instead of filename::

        def get_gridfile_by_id(bucket, filename, request):
            # "filename" is interpreted as _id instead of name.
            # Return a Future AsyncIOMotorGridOut.
            return bucket.open_download_stream(file_id=filename)

        client = AsyncIOMotorClient()
        gridfs_handler = AIOHTTPGridFS(client.my_database,
                                       get_gridfs_file=get_gridfile_by_id)

    :Parameters:
      - `bucket`: An :class:`~motor.motor_asyncio.AsyncIOMotorGridFSBucket`
      - `filename`: A string, the URL portion matching {filename} in the URL
        pattern
      - `request`: An :class:`aiohttp.web.Request`
    )open_download_stream_by_name)bucketfilenamerequests      Z/var/www/app.qaans.com/backend/venv/lib/python3.11/site-packages/motor/aiohttp/__init__.pyget_gridfs_filer       s    < ..x888    c                     dS )a5  Override to customize cache control behavior.

    Return a positive number of seconds to trigger aggressive caching or 0
    to mark resource as cacheable, only. 0 is the default.

    For example, to allow image caching::

        def image_cache_time(filename, modified, mime_type):
            if mime_type.startswith('image/'):
                return 3600

            return 0

        client = AsyncIOMotorClient()
        gridfs_handler = AIOHTTPGridFS(client.my_database,
                                       get_cache_time=image_cache_time)

    :Parameters:
      - `filename`: A string, the URL portion matching {filename} in the URL
        pattern
      - `modified`: A datetime, when the matching GridFS file was created
      - `mime_type`: The file's type, a string like "application/octet-stream"
    r    )r	   modified	mime_types      r   get_cache_timer   A   s	    0 1r   c                     dS )a,  Override to modify the response before sending to client.

    For example, to allow image caching::

        def gzip_header(response, gridout):
            response.headers['Content-Encoding'] = 'gzip'

        client = AsyncIOMotorClient()
        gridfs_handler = AIOHTTPGridFS(client.my_database,
                                       set_extra_headers=gzip_header)

    :Parameters:
      - `response`: An :class:`aiohttp.web.Response`
      - `gridout`: The :class:`~motor.motor_asyncio.AsyncIOMotorGridOut` we
        will serve to the client
    Nr   )responsegridouts     r   set_extra_headersr   \   s	    " 	Dr   c                     	 | j         j        j                                        d         }d|z  }n# t          t
          f$ r d| z  }Y nw xY wt          j                            |          d )N	formatterz<Bad AIOHTTPGridFS route "%s", requires a {filename} variablez'Bad AIOHTTPGridFS route for request: %stext)	
match_inforouteresourceget_infoKeyErrorAttributeErroraiohttpwebHTTPInternalServerError)r
   r   msgs      r   _config_errorr%   p   s    B&,5>>@@M	LyXn% B B B7'AB +
-
-3
-
7
7TAs   .1 A
	A
c                   .    e Zd ZdZdeeefdZd Zd Z	dS )AIOHTTPGridFSa.  Serve files from `GridFS`_.

    This class is a :ref:`request handler <aiohttp-web-handler>` that serves
    GridFS files, similar to aiohttp's built-in static file server.

    .. code-block:: python

        client = AsyncIOMotorClient()
        gridfs_handler = AIOHTTPGridFS(client.my_database)

        app = aiohttp.web.Application()

        # The GridFS URL pattern must have a "{filename}" variable.
        resource = app.router.add_resource('/fs/{filename}')
        resource.add_route('GET', gridfs_handler)
        resource.add_route('HEAD', gridfs_handler)

        app_handler = app.make_handler()
        server = loop.create_server(app_handler, port=80)

    By default, requests' If-Modified-Since headers are honored, but no
    specific cache-control timeout is sent to clients. Thus each request for
    a GridFS file requires a quick check of the file's ``uploadDate`` in
    MongoDB. Pass a custom :func:`get_cache_time` to customize this.

    :Parameters:
      - `database`: An :class:`AsyncIOMotorDatabase`
      - `get_gridfs_file`: Optional override for :func:`get_gridfs_file`
      - `get_cache_time`: Optional override for :func:`get_cache_time`
      - `set_extra_headers`: Optional override for :func:`set_extra_headers`

    .. _GridFS: https://www.mongodb.com/docs/manual/core/gridfs/
    fsc                     t          |t                    st          d|z            || _        t	          | j        |          | _        || _        || _        || _        d S )NzDFirst argument to AIOHTTPGridFS must be AsyncIOMotorDatabase, not %r)	
isinstancer   	TypeError	_databaser   _bucket_get_gridfs_file_get_cache_time_set_extra_headers)selfdatabaseroot_collectionr   r   r   s         r   __init__zAIOHTTPGridFS.__init__   sl     ($899 	VYaa   "/PP /-"3r   c                   K   	 |j         d         }n# t          $ r t          |           Y nw xY w|j        dvr(t          j                            |j        ddh          	 |                     | j        ||           d{V }n8# t          j
        $ r& t          j                            |j                  w xY wt          j                                        }t          |          }|                     |j        |||           |                     ||           |j        }|X|                    |j        j                  }|j                            d	
          }||k    r|                    d           |S |j                            d          }	|	0|	                    d          |k    r|                    d           |S |j        |_        |                    |           d{V  |j        dk    red	}
|
|j        k     rX|                    |j                   d{V }|                    |           d{V  |
t?          |          z  }
|
|j        k     X|S )z&Send filepath to client using request.r	   )GETHEADr6   r7   )methodallowed_methodsNr   )tzinfor   )microsecondi0  zIf-None-Match") r   r   r%   r8   r!   r"   HTTPMethodNotAllowedr.   r-   gridfsNoFileHTTPNotFoundpathStreamResponser   _set_standard_headersr0   if_modified_sincereplaceupload_dater:   
set_statusheadersgetstriplengthcontent_lengthprepareread
chunk_sizewritelen)r1   r
   r	   r   respchecksum	ims_valueif_sincer   etagwrittenchunks               r   __call__zAIOHTTPGridFS.__call__   s     	#)*5HH 	# 	# 	#'"""""	# >00+22~v 3   	> 11$,'RRRRRRRRGG} 	> 	> 	>+***===	> {))++ !))""7<wIII 	g... -	  !((0C0J(KKH*22q2AAH8##$$$ ""?33

38 ; ;OOC   K%nll7#########>U""GGN**%ll7+=>>>>>>>>jj'''''''''3u::%	 GN**
 s    ..#"B 5B;c                    |j         |_        |j        }|t          j        |          \  }}|r||_        d|z  |j        d<   |                     ||j         |j                  }|dk    rkt          j                                        t          j	        |          z   
                    d          |j        d<   dt          |          z   |j        d<   d S d	|j        d<   d S )
Nz"%s"Etagr   )secondsz%a, %d %b %Y %H:%M:%S GMTExpireszmax-age=zCache-Controlpublic)rF   last_modifiedcontent_type	mimetypes
guess_typerH   r/   datetimeutcnow	timedeltastrftimestr)r1   rA   rR   r   rS   r`   encoding
cache_times           r   rC   z#AIOHTTPGridFS._set_standard_headers   s    $0+%.%9$%?%?"L( 	- ,D%0V ))$0CWEYZZ
>>!((**X-?
-S-S-SSh233 L# -7Z,HDL))),4DL)))r   N)
__name__
__module____qualname____doc__r   r   r   r4   rY   rC   r   r   r   r'   r'   {   s`           J '%+4 4 4 4&7 7 7r5 5 5 5 5r   r'   )rm   rc   ra   aiohttp.webr!   r>   motor.motor_asyncior   r   motor.motor_gridfsr   r   r   r   r%   r'   r   r   r   <module>rq      s               N N N N N N N N , , , , , ,9 9 9B  6	 	 	(B B BD5 D5 D5 D5 D5 D5 D5 D5 D5 D5r   