
    	]j                     v   d Z ddlZddlZddlZddlZddlmZ ddlmZ ddl	m
Z
 ddlmZmZmZ ddlmZmZmZmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZmZ ddl m!Z!  ejD                  e#      Z$	 dee%   de%de&fdZ'dede%dee%   defdZ(	  ed       edg       ee!g      d                      Z)y)zA
HTTP views dedicated to LocalFiles storage download operations.
    N)Path)Optional)settings)	CharFieldFValue)HttpRequestHttpResponseHttpResponseForbiddenHttpResponseNotFoundHttpResponseNotModified)	safe_join)extend_schema)LocalFilesImportStorage)RangedFileResponse)api_viewpermission_classes)IsAuthenticatedheader_valueetagreturnc                     | sy| j                  d      D cg c]#  }|j                         s|j                         % }}d|v xs ||v S c c}w )zKReturn True if the client's cached representation matches the current file.F,*)splitstrip)r   r   	candidateetag_candidatess       S/root/env/lib/python3.12/site-packages/label_studio/io_storages/localfiles/views.py_if_none_match_satisfiedr       sT    :F:L:LS:QgYU^UdUdUfy(gOg/!<T_%<< hs
   AArequest	full_pathif_none_match_headerc                    	 t        |d      }t        j                  |j                               }t        |dt        |j                  dz              }d|d	d
|j                  d	d}t        ||      r!|j                          t               }||d<   |S t        j                   t#        |            \  }	}
|	xs d}	t%        | ||	      }||d<   |S # t        $ r/}t        j                  d||       t	        d|       cY d}~S d}~ww xY w)z
    Stream the requested file and attach a weak ETag so browsers can cache it.

    We also honor `If-None-Match` headers to short-circuit the response with 304
    when the client's cached representation is still valid.
    rb)modezError opening file %s: %szError opening file Nst_mtime_nsi ʚ;zW/"x-"ETagzapplication/octet-stream)content_type)openOSErrorloggererrorr   osfstatfilenogetattrintst_mtimest_sizer    closer   	mimetypes
guess_typestrr   )r!   r"   r#   file_handleexcstat_resultmtime_nsr   not_modifiedr,   _responses               r   build_localfile_responserC   %   s   G940 ((;--/0K{M3{7K7Km7[3\]H!Ak11!4A6D   4d;.0#V  **3y>:OL!=#=L!';\RHHVO-  G0)SA#&9)$EFFGs   C 	D$D DDT)excludeGETc                 r     j                   j                  d      }t        j                  du rt	        d      S t        j
                  }|rb j                  j                  rKt        j                  |      j                  d      }t        t        ||            }d}t        j                  j                  t        j                  j                  t!        |                  }t"        j$                  j'                  t)        |t+                           j-                  t/        d            }|j1                         rt3         fd	|D              }|rOt        j                  j1                  |      r0t5         t!        |       j6                  j                  d
            S t9               S t	               S )zKServe files residing under LocalFilesImportStorage roots with ETag support.dFzServing local files can be dangerous, so it's disabled by default. You can enable it with LOCAL_FILES_SERVING_ENABLED environment variable, please check docs: https://labelstud.io/guide/storage.html#Local-storage/)output_field)
_full_pathpath)_full_path__startswithc              3   h   K   | ])  }|j                   j                  j                         + y w)N)projecthas_permissionuser).0storager!   s     r   	<genexpr>z"localfiles_data.<locals>.<genexpr>k   s%     &vX_w'E'Egll'S&vs   /2HTTP_IF_NONE_MATCH)r!   r"   r#   )rE   getr   LOCAL_FILES_SERVING_ENABLEDr   LOCAL_FILES_DOCUMENT_ROOTrP   is_authenticated	posixpathnormpathlstripr   r   r1   rK   dirnamer;   r   objectsannotater   r   filterr   existsanyrC   METAr   )r!   rK   local_serving_document_rootr"   user_has_permissionsfull_path_dirlocalfiles_storages   `      r   localfiles_datarg   P   s\   
 ;;??3D++u4$W
 	
 #+"D"D--!!$'..s3#>EF	$ ((Y)HI4<<EE]E F 

&&	&
2 	 $$&#&&vcu&v#v   BGGNN9$=+i.%,\\%5%56J%K  ()) ""    )*__doc__loggingr9   r1   rY   pathlibr   typingr   django.confr   django.db.modelsr   r   r   django.httpr	   r
   r   r   r   django.utils._osr   drf_spectacular.utilsr   io_storages.localfiles.modelsr   ranged_fileresponser   rest_framework.decoratorsr   r   rest_framework.permissionsr   	getLogger__name__r/   r;   boolr    rC   rg    rh   r   <module>rz      s      	      0 0 w w & / A 2 B 6			8	$
=8C= = = =### #3-# 	#L
 t	5'_%&%# '  %#rh   