o
    ihL                     @   s   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	 ddlm
Z
 ddlmZ dd	lmZ dd
lmZ dZddddiiZG dd deZG dd deZG dd deZdd ZG dd deZG dd de
eZdS )    N)errors)MediaIoBaseUploadwraps   )ApiAttribute)ApiAttributeMixin)ApiResource)ApiResourceList)LoadAuthi   z$application/vnd.google-apps.document
text/plainu   ﻿utf8c                   @      e Zd ZdZdS )FileNotUploadedErrorz=Error trying to access metadata of file that is not uploaded.N__name__
__module____qualname____doc__ r   r   H/var/www/edux/Edux_v2/venv/lib/python3.10/site-packages/pydrive/files.pyr          r   c                   @   r   )ApiRequestErrorz$Error while making any API requests.Nr   r   r   r   r   r      r   r   c                   @   r   )FileNotDownloadableErrorz7Error trying to download file that is not downloadable.Nr   r   r   r   r   r      r   r   c                    s   t   fdd}|S )zwDecorator to check if the file has metadata and fetches it if not.

  :raises: ApiRequestError, FileNotUploadedError
  c                    s$   | j s|    | g|R i |S N)uploadedFetchMetadata)selfargskwargs	decorateer   r   
_decorated'   s   z LoadMetadata.<locals>._decoratedr   )r!   r"   r   r    r   LoadMetadata"   s   r#   c                       s.   e Zd ZdZd fdd	Zedd Z  ZS )GoogleDriveFileListzOGoogle Drive FileList instance.

  Equivalent to Files.list() in Drive APIs.
  Nc                    s   t t| j||d dS )z*Create an instance of GoogleDriveFileList.)authmetadataN)superr$   __init__)r   r%   param	__class__r   r   r(   5   s   zGoogleDriveFileList.__init__c                 C   sZ   | j j jdi t| j| jd| _g }| jd D ]}t| j |dd}|	| q|S )zOverwritten method which actually makes API call to list files.

    :returns: list -- list of pydrive.files.GoogleDriveFile.
    httpitemsT)r%   r&   r   Nr   )
r%   servicefileslistdictexecuter-   r&   GoogleDriveFileappend)r   resultfile_metadatatmp_filer   r   r   _GetList9   s   zGoogleDriveFileList._GetList)NN)r   r   r   r   r(   r   r9   __classcell__r   r   r*   r   r$   /   s
    r$   c                   @   s\  e Zd ZdZedZedZedZd<ddZd	d
 Z	d=ddZ
dd Zd>ddZd?ddZed?ddZed?ddZd@ddZd@ddZd@ddZd@ddZd d! Zed"d# Zd$d% Zed@d&d'Zed@d(d)Zed@d*d+Zed@d,d-Zeed@d.d/Zeed@d0d1Zd2d3 Zed4d5 Z ed6d7 Z!e"e#fd8d9Z$e"e#fd:d;Z%dS )Ar4   z}Google Drive File instance.

  Inherits ApiResource which inherits dict.
  Can access and modify metadata like dictionary.
  contentr   r&   NFc                 C   s^   t |  t|  i | _ddi| _|| _|| _|r | | n|r'| | d| _	d| _
dS )aD  Create an instance of GoogleDriveFile.

    :param auth: authorized GoogleAuth instance.
    :type auth: pydrive.auth.GoogleAuth
    :param metadata: file resource to initialize GoogleDriveFile with.
    :type metadata: dict.
    :param uploaded: True if this file is confirmed to be uploaded.
    :type uploaded: bool.
    r;   Fa  alternateLink,appDataContents,canComment,canReadRevisions,copyable,createdDate,defaultOpenWithLink,description,downloadUrl,editable,embedLink,etag,explicitlyTrashed,exportLinks,fileExtension,fileSize,folderColorRgb,fullFileExtension,headRevisionId,iconLink,id,imageMediaMetadata,indexableText,isAppAuthorized,kind,labels,lastModifyingUser,lastModifyingUserName,lastViewedByMeDate,markedViewedByMeDate,md5Checksum,mimeType,modifiedByMeDate,modifiedDate,openWithLinks,originalFilename,ownedByMe,ownerNames,owners,parents,permissions,properties,quotaBytesUsed,selfLink,shareable,shared,sharedWithMeDate,sharingUser,spaces,thumbnail,thumbnailLink,title,userPermission,version,videoMediaMetadata,webContentLink,webViewLink,writersCanShareTN)r   r(   r	   r&   dirtyr%   r   UpdateMetadataupdate_ALL_FIELDShas_bom)r   r%   r&   r   r   r   r   r(   U   s   





zGoogleDriveFile.__init__c              
   C   sf   zt | |W S  ty2 } z| jrt|| dr+|   t | |W  Y d}~S t d}~ww )a:  Overwrites manner of accessing Files resource.

    If this file instance is not uploaded and id is specified,
    it will try to look for metadata with Files.get().

    :param key: key of dictionary query.
    :type key: str.
    :returns: value of Files resource
    :raises: KeyError, FileNotUploadedError
    idN)r2   __getitem__KeyErrorr   getr   r   )r   keyer   r   r   rB   z   s   
zGoogleDriveFile.__getitem__utf-8c                 C   s0   t ||| _| ddu rd| d< dS dS )aQ  Set content of this file to be a string.

    Creates io.BytesIO instance of utf-8 encoded string.
    Sets mimeType to be 'text/plain' if not specified.

    :param encoding: The encoding to use when setting the content of this file.
    :type encoding: str
    :param content: content of the file in string.
    :type content: str
    mimeTypeNr   )ioBytesIOencoder;   rD   )r   r;   encodingr   r   r   SetContentString   s   z GoogleDriveFile.SetContentStringc                 C   sJ   t |d| _| ddu r|| d< | ddu r#t|d | d< dS dS )a,  Set content of this file from a file.

    Opens the file specified by this method.
    Will be read, uploaded, and closed by Upload() method.
    Sets metadata 'title' and 'mimeType' automatically if not specified.

    :param filename: name of the file to be uploaded.
    :type filename: str.
    rbtitleNrH   r   )openr;   rD   	mimetypes
guess_type)r   filenamer   r   r   SetContentFile   s   
zGoogleDriveFile.SetContentFilec                 C   s@   | j du st| j tjus| j|kr| || | j  |S )a  Get content of this file as a string.

    :param mimetype: The mimetype of the content string.
    :type mimetype: str

    :param encoding: The encoding to use when decoding the byte string.
    :type encoding: str

    :param remove_bom: Whether to strip a known BOM.
    :type remove_bom: bool

    :returns: str -- utf-8 decoded content of the file
    :raises: ApiRequestError, FileNotUploadedError, FileNotDownloadableError
    N)r;   typerI   rJ   r@   FetchContentgetvaluedecode)r   mimetyperL   
remove_bomr   r   r   GetContentString   s
   

z GoogleDriveFile.GetContentStringc                 C   sV   | j du st| j tjus| j|kr| || t|d}|| j   |	  dS )ag  Save content of this file as a local file.

    :param filename: name of the file to write to.
    :type filename: str
    :param mimetype: mimeType of the file.
    :type mimetype: str
    :param remove_bom: Whether to remove the byte order marking.
    :type remove_bom: bool
    :raises: ApiRequestError, FileNotUploadedError, FileNotDownloadableError
    Nwb)
r;   rU   rI   rJ   r@   rV   rP   writerW   close)r   rS   rY   rZ   fr   r   r   GetContentFile   s   


zGoogleDriveFile.GetContentFilec              
   C   s   | j dp
| d}|r| j}|r@z| jj j||dj| jd}W n tj	y5 } zt
|d}~ww d| _| | dS t )aD  Download file's metadata from id using Files.get().

    :param fields: The fields to include, as one string, each entry separated
    by commas, e.g. 'fields,labels'.
    :type fields: str

    :param fetch_all: Whether to fetch all fields.
    :type fetch_all: bool

    :raises: ApiRequestError, FileNotUploadedError
    rA   )fileIdfieldsr,   NT)r&   rD   r?   r%   r/   r0   r3   r-   r   	HttpErrorr   r   r=   r   )r   rb   	fetch_allfile_idr&   errorr   r   r   r      s"   
zGoogleDriveFile.FetchMetadatac                 C   s   | j d}| j d}|rt| || _d| jd< n|r6||r6t| ||| _d| jd< ntd|dkrS|rU| | jt	| d  |  | | _
dS dS dS )	z}Download file's content from download_url.

    :raises: ApiRequestError, FileNotUploadedError, FileNotDownloadableError
    downloadUrlexportLinksFr;   z:No downloadLink/exportLinks for mimetype found in metadatar   rH   N)r&   rD   rI   rJ   _DownloadFromUrlr;   r<   r   _RemovePrefixMIME_TYPE_TO_BOMr@   )r   rY   rZ   download_urlexport_linksr   r   r   rV      s&   zGoogleDriveFile.FetchContentc                 C   sN   | j s
| ddur| jd r| j|d dS | j|d dS | j|d dS )zUpload/update file by choosing the most efficient method.

    :param param: additional parameter to upload file.
    :type param: dict.
    :raises: ApiRequestError
    rA   Nr;   r)   )r   rD   r<   _FilesUpdate_FilesPatch_FilesInsertr   r)   r   r   r   Upload  s
   
zGoogleDriveFile.Uploadc                 C      | j |d dS )z<Move a file to the trash.

    :raises: ApiRequestError
    rn   N)_FilesTrashrr   r   r   r   Trash  s   zGoogleDriveFile.Trashc                 C   rt   )zMove a file out of the trash.
    :param param: Additional parameter to file.
    :type param: dict.
    :raises: ApiRequestError
    rn   N)_FilesUnTrashrr   r   r   r   UnTrash&  s   zGoogleDriveFile.UnTrashc                 C   rt   )z}Hard-delete a file.

    :param param: additional parameter to file.
    :type param: dict.
    :raises: ApiRequestError
    rn   N)_FilesDeleterr   r   r   r   Delete.  s   zGoogleDriveFile.Deletec              
   C   sh   | j dp	| d }z| jj j||dj| jd}W n tj	y- } zt
|d}~ww |   |S )a.  Insert a new permission. Re-fetches all permissions after call.

    :param new_permission: The new permission to insert, please see the
    official Google Drive API guide on permissions.insert for details.

    :type new_permission: object

    :return: The permission object.
    :rtype: object
    rA   )ra   bodyr,   N)r&   rD   r%   r/   permissionsinsertr3   r-   r   rc   r   GetPermissions)r   new_permissionre   
permissionrf   r   r   r   InsertPermission7  s   
z GoogleDriveFile.InsertPermissionc                 C   s   | j dd | jdS )zDownloads all permissions from Google Drive, as this information is
    not downloaded by FetchMetadata by default.

    :return: A list of the permission objects.
    :rtype: object[]
    r|   )rb   )r   r&   rD   r   r   r   r   r~   M  s   zGoogleDriveFile.GetPermissionsc                 C   s
   |  |S )zDeletes the permission specified by the permission_id.

    :param permission_id: The permission id.
    :type permission_id: str
    :return: True if it succeeds.
    :rtype: bool
    )_DeletePermission)r   permission_idr   r   r   DeletePermissionX  s   
z GoogleDriveFile.DeletePermissionc              
   C   s   |du ri }|   |d< z| jd r|  |d< | jj jdi |j| jd}W n t	j
y; } zt|d}~ww d| _d| jd< | | dS )	zUpload a new file using Files.insert().

    :param param: additional parameter to upload file.
    :type param: dict.
    :raises: ApiRequestError
    Nr{   r;   
media_bodyr,   TFr   )
GetChangesr<   _BuildMediaBodyr%   r/   r0   r}   r3   r-   r   rc   r   r   r=   r   r)   r&   rf   r   r   r   rq   b  s    


zGoogleDriveFile._FilesInsertc              
   C   s   |du ri }| j dp| d |d< z| jj jd	i |j| jd W n tj	y6 } zt
|d}~ww | j rAd| j d d< dS )
zUn-delete (Trash) a file using Files.UnTrash().
    :param param: additional parameter to file.
    :type param: dict.
    :raises: ApiRequestError
    NrA   ra   r,   FlabelstrashedTr   )r&   rD   r%   r/   r0   untrashr3   r-   r   rc   r   r   r)   rf   r   r   r   rw   y  s   
zGoogleDriveFile._FilesUnTrashc              
   C   s   |du ri }| j dp| d |d< z| jj jdi |j| jd W n tj	y6 } zt
|d}~ww | j rAd| j d d< dS )	zSoft-delete (Trash) a file using Files.Trash().

    :param param: additional parameter to file.
    :type param: dict.
    :raises: ApiRequestError
    NrA   ra   r,   Tr   r   r   )r&   rD   r%   r/   r0   trashr3   r-   r   rc   r   r   r   r   r   ru     s   
zGoogleDriveFile._FilesTrashc              
   C   sp   |du ri }| j dp| d |d< z| jj jdi |j| jd W dS  tj	y7 } zt
|d}~ww )zDelete a file using Files.Delete()
    (WARNING: deleting permanently deletes the file!)

    :param param: additional parameter to file.
    :type param: dict.
    :raises: ApiRequestError
    NrA   ra   r,   Tr   )r&   rD   r%   r/   r0   deleter3   r-   r   rc   r   r   r   r   r   ry     s   	$zGoogleDriveFile._FilesDeletec              
   C   s   |du ri }|   |d< | jd|d< z| jd r |  |d< | jj jd
i |j	| j
d}W n tjyC } zt|d}~ww d| _d	| jd< | | dS )zUpdate metadata and/or content using Files.Update().

    :param param: additional parameter to upload file.
    :type param: dict.
    :raises: ApiRequestError, FileNotUploadedError
    Nr{   rA   ra   r;   r   r,   TFr   )r   r&   rD   r<   r   r%   r/   r0   r>   r3   r-   r   rc   r   r   r=   r   r   r   r   ro     s"   	


zGoogleDriveFile._FilesUpdatec              
   C   s   |du ri }|   |d< | jd|d< z| jj jdi |j| jd}W n t	j
y8 } zt|d}~ww | | dS )zUpdate metadata using Files.Patch().

    :param param: additional parameter to upload file.
    :type param: dict.
    :raises: ApiRequestError, FileNotUploadedError
    Nr{   rA   ra   r,   r   )r   r&   rD   r%   r/   r0   patchr3   r-   r   rc   r   r=   r   r   r   r   rp     s   	
zGoogleDriveFile._FilesPatchc                 C   s*   |  ddu rd| d< t| j| d ddS )zBuild MediaIoBaseUpload to get prepared to upload content of the file.

    Sets mimeType as 'application/octet-stream' if not specified.

    :returns: MediaIoBaseUpload -- instance that will be used to upload content.
    rH   Nzapplication/octet-streamT)	resumable)rD   r   r;   r   r   r   r   r     s   zGoogleDriveFile._BuildMediaBodyc                 C   s*   | j |\}}|jdkrtd| |S )zDownload file from url using provided credential.

    :param url: link of the file to download.
    :type url: str.
    :returns: str -- content of downloaded file in string.
    :raises: ApiRequestError
       zCannot download file: %s)r-   requeststatusr   )r   urlrespr;   r   r   r   ri     s   	
z GoogleDriveFile._DownloadFromUrlc              
      s   | j dp	| d }z| jj j| d  W n tjy* } zt	|d}~ww d| v rLd| j v rL| d } fdd}t
||}|| d< || j d< dS )zDeletes the permission remotely, and from the file object itself.

    :param permission_id: The ID of the permission.
    :type permission_id: str

    :return: The permission
    :rtype: object
    rA   )ra   permissionIdNr|   c                    s   | d  kS )NrA   r   )perr   r   r   <lambda>  s    z3GoogleDriveFile._DeletePermission.<locals>.<lambda>T)r&   rD   r%   r/   r|   r   r3   r   rc   r   filter)r   r   re   rf   r|   is_not_current_permissionr   r   r   r     s"   



z!GoogleDriveFile._DeletePermissionc           	      C   s   t |}| |}||krO| |}t |}|| }d}|dkrF| | | | |t |7 }| | | |}t |}||7 }|dks | ||  dS dS )a*  Deletes passed prefix by shifting content of passed file object by to
    the left. Operation is in-place.

    Args:
      file_object (obj): The file object to manipulate.
      prefix (str): The prefix to insert.
      block_size (int): The size of the blocks which are moved one at a time.
    r   N)lenreadseekr]   truncate)	file_objectprefix
block_sizeprefix_lengthcontent_startblock_to_writecurrent_block_lengthread_locationwrite_locationr   r   r   rj     s$   






zGoogleDriveFile._RemovePrefixc                 C   s   |  |}|  |}|d }| d | | t|}t|rD| | | | ||7 }|}| | |  |}||7 }t|s dS dS )zInserts the passed prefix in the beginning of the file, operation is
    in-place.

    Args:
      file_object (obj): The file object to manipulate.
      prefix (str): The prefix to insert.
       r   N)r   r   r]   r   )r   r   r   first_blocksecond_blockr   r   r   r   r   _InsertPrefix=  s   








zGoogleDriveFile._InsertPrefix)NNF)rG   )NrG   F)NFr   )&r   r   r   r   r   r;   r   r&   r(   rB   rM   rT   r[   r`   r   r   r#   rV   rs   rv   rx   rz   r   r~   r   rq   rw   ru   ry   ro   rp   r   ri   r   staticmethod
BLOCK_SIZErj   r   r   r   r   r   r4   K   s\    
%






	




'r4   )rI   rQ   	apiclientr   apiclient.httpr   	functoolsr   apiattrr   r   r	   r
   r%   r   r   rK   rk   RuntimeErrorr   IOErrorr   r   r#   r$   r4   r   r   r   r   <module>   s*    
