
    9h$                     p    S r SSKrSSKrSSKrSSKrSSKJrJr  SSK	J
r
  S rS rS rS r " S	 S
5      rg)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                 $    U R                  U5      $ )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      [C:\Suresh\moveshuttle\MDcreated\moveengine\venv\Lib\site-packages\motor/aiohttp/__init__.pyget_gridfs_filer   "   s    < ..x88    c                     g)a  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   C   s    0 r   c                     g)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    r   c                      U R                   R                  R                  R                  5       S   nSU-  n[        R                  R                  US9S e! [        [
        4 a    SU -  n N5f = f)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%   q   su    B&&,,55>>@M	LyX
 ++
-
-3
-
7TA	 n% B7'ABs   6A A.-A.c                   6    \ rS rSrSrS\\\4S jrS r	S r
Srg)	AIOHTTPGridFS|   a  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                     [        U[        5      (       d  [        SU-  5      eXl        [	        U R                  U5      U l        X0l        X@l        XPl        g )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__AIOHTTPGridFS.__init__   sS     ($899VYaa  "/P /-"3r   c                   #     UR                   S   nUR                  S;  a*  [        R
                  R                  UR                  SS1S9e U R                  U R                  WU5      I Sh  vN n[        R
                  R                  5       n[        U5      nU R                  UR                  XSU5        U R!                  XS5        UR"                  nUbT  UR%                  UR&                  R(                  S9nUR&                  R%                  S	S
9n	X:  a  UR+                  S5        U$ UR,                  R/                  S5      n
U
b(  U
R1                  S5      U:X  a  UR+                  S5        U$ UR2                  Ul        UR7                  U5      I Sh  vN   UR                  S:X  al  S	nXR2                  :  a[  UR9                  UR:                  5      I Sh  vN nUR=                  U5      I Sh  vN   U[?        U5      -  nXR2                  :  a  M[  U$ ! [         a    [        U5         GN f = f GN! [        R                   a-  n[        R
                  R                  UR                  S9UeSnAff = f N N N7f)z&Send filepath to client using request.r	   )GETHEADr8   r9   )methodallowed_methodsNr   tzinfor   )microsecondi0  zIf-None-Match") r   r   r%   r:   r!   r"   HTTPMethodNotAllowedr/   r.   gridfsNoFileHTTPNotFoundpathStreamResponser   _set_standard_headersr1   if_modified_sincereplaceupload_dater=   
set_statusheadersgetstriplengthcontent_lengthprepareread
chunk_sizewritelen)r2   r
   r	   r   erespchecksum	ims_valueif_sincer   etagwrittenchunks                r   __call__AIOHTTPGridFS.__call__   s=    	#))*5H >>0++22~~v 3  	E 11$,,'RRG {{))+ !)""7<<I 	. --	  !((0C0C0J0J(KH**22q2AH#$ ""?3

38 ;OOC K%nnll7###>>U"GNN*%ll7+=+=>>jj'''3u:%	 NN*
 g  	#'"	# S}} 	E++***=1D	E@ 	$ ?'s   JH :J H: .H7/H: 3D%JI>AJJ J5J6!JJH40J3H44J7H: :I;(I66I;;J JJc                 J   UR                   Ul        UR                  nUc  [        R                  " U5      u  pVU(       a  XRl        SU-  UR
                  S'   U R                  XR                   UR                  5      nUS:  a  [        R                  R                  [        R                  R                  5      R                  S S9[        R                  " US9-   R                  S5      UR
                  S'   S[        U5      -   UR
                  S	'   g S
UR
                  S	'   g )Nz"%s"Etagr   r<   )secondsz%a, %d %b %Y %H:%M:%S GMTExpireszmax-age=zCache-Controlpublic)rI   last_modifiedcontent_type	mimetypes
guess_typerK   r0   datetimenowtimezoneutcrH   	timedeltastrftimestr)r2   rD   rV   r   rW   re   encoding
cache_times           r   rF   #AIOHTTPGridFS._set_standard_headers   s    $00++%.%9%9$%?"L ,%0V ))$0C0CWEYEYZ
>!!%%h&7&7&;&;<DDDDQ$$Z89h23 LL#
 -7Z,HDLL),4DLL)r   )r.   r-   r0   r/   r1   N)__name__
__module____qualname____firstlineno____doc__r   r   r   r5   r]   rF   __static_attributes__r   r   r   r'   r'   |   s&     J '%+4&7r5r   r'   )rv   rh   rf   aiohttp.webr!   rA   motor.motor_asyncior   r   motor.motor_gridfsr   r   r   r   r%   r'   r   r   r   <module>r{      s@        N ,
9B6&BE5 E5r   