
    Bff                     H    d dl m Z   G d d          Z G d de          ZdS )    datetimec                       e Zd ZdZdZed             Zd Zd Zd Z	d Z
d Zd	 Zd
 Zd Zd Zed             Zed             ZdS )InventoryReporta  
    A utility class for fetching and processing inventory reports from GCS.

    The 'InventoryReport' class provides logic to support logic to fetch
    inventory reports, and process their content to obtain a final snapshot
    of objects in the latest inventory reports.

    High-Level Functionality:
    ------------------------
    1. Fetching Inventory Reports:
       - The class offers methods to fetch inventory report configurations and
         metadata from GCS.
       - It validates the inventory report information provided by the user.
       - Inventory report configurations include options for parsing CSV format
         and specifying the bucket and destination path.

    2. Parsing and Processing Inventory Report Content:
       - The class processes the raw content of inventory reports to extract
         object details such as name, size, etc.
       - It supports listing objects using a snapshot option or filtering
         based on a user-defined prefix.
       - The class handles CSV parsing, removes header (if specified), and
         fetches required object metadata.

    3. Constructing the Final Snapshot:
       - If the user wishes to use the snapshot to do listing directly, the
         snapshot will contain the relevant object details and subdirectory
         prefixes, filtered by the prefix.

       - If the user wishes to use the snapshot as a starting point for async
         listing, the snapshot will only contain a list of object names,
         filtered by the prefix.

    Note:
    -----
    - The class should only be internally used in the 'GCSFileSystem' as an
      optional configuration during listing.

    Example Usage:
    --------------
    # Should already be instanted in 'core.py'
    gcs_file_system = GCSFileSystem(...)

    # User defines inventory report information
    inventory_report_info = {
        "use_snapshot_listing": True,
        "location": "us-east1",
        "id": "inventory_report_id"
    }

    # User defines a prefix for filtering objects
    prefix = "prefix/"

    # Fetch the snapshot based on inventory reports
    items, prefixes = await InventoryReport.fetch_snapshot(
    gcs_file_system, inventory_report_info, prefix)
    z)https://storageinsights.googleapis.com/v1c                 0  K   |                      |           |                    d          }|                    d          }|                    d          }|                     |||           d{V }|                     ||          }|                     ||           d{V }	|                     |	          }
|j        }|                     ||
|	           d{V }|                     |||||
          }| 	                    |||          }|S )a  
        Main entry point of the 'InventoryReport' class.
        Fetches the latest snapshot of objects based on inventory report configuration.

        Parameters:
            gcs_file_system (GCSFileSystem): An instance of the 'GCSFileSystem'
            class (see 'core.py').
            inventory_report_info (dict): A client-configured dictionary
            containing inventory report information.
            prefix (str): Listing prefix specified by the client.

        Returns:
            tuple: A tuple containing two lists: the 'items' list representing
            object details for the snapshot, and the 'prefixes' list containing
            subdirectory prefixes.

            Note: when 'use_snapshot_listing' in 'inventory_report_info' is set
            to False, the 'prefixes' list will be empty, and the 'items' list
            will contain only the object names.
        use_snapshot_listinglocationid)gcs_file_systemr	   r
   N)raw_inventory_report_configr   )r   inventory_report_config"unsorted_inventory_report_metadata)r   inventory_report_metadatabucket)r   inventory_report_contentr   r   r   )objectsprefixr   )
_validate_inventory_report_infoget"_fetch_raw_inventory_report_config"_parse_raw_inventory_report_config _fetch_inventory_report_metadata_sort_inventory_report_metadatar   "_download_inventory_report_content_parse_inventory_report_content_construct_final_snapshot)clsr   inventory_report_infor   r   inventory_report_locationinventory_report_idr   r   r   r   r   r   r   snapshots                  e/home/panchajanya/Development/work/volatility3/lib/python3.11/site-packages/gcsfs/inventory_report.pyfetch_snapshotzInventoryReport.fetch_snapshotB   s     . 	++,ABBB  5889OPP$9$=$=j$I$I!377== -0,R,R+." -S -
 -
 '
 '
 '
 '
 '
 '
# #&"H"H(C!5 #I #
 #
 473W3W+$; 4X 4
 4
 .
 .
 .
 .
 .
 .
* %($G$G/Q %H %
 %
!
 )/),)O)O+&? *P *
 *
 $
 $
 $
 $
 $
 $
  55+%=$;!5 6 
 
 00FAU 1 
 

     c                 x    d| vrt          d          d| vrt          d          d| vrt          d          dS )a  
        Validates the inventory report information dictionary that user
        passes in.

        Parameters:
            inventory_report_info (dict): A dictionary containing the inventory
            report information with the following keys:
                - "use_snapshot_listing" (bool): A flag indicating whether
                  to use snapshot listing in the inventory report.
                - "location" (str): The location of the inventory report in GCS.
                - "id" (str): The ID of the inventory report in GCS.

        Raises:
            ValueError: If any required key (use_snapshot_listing, location, id)
            is missing from the inventory_report_info dictionary.
        r   z'Use snapshot listing is not configured.r	   z,Inventory report location is not configured.r
   z&Inventory report id is not configured.N)
ValueError)r   s    r#   r   z/InventoryReport._validate_inventory_report_info   s]    " ")>>>FGGG222KLLL,,,EFFF -,r%   c                    K   | j         }d}|                    t          j        |||          }	 |                     d|d           d{V }|S # t
          $ r}t          d| d          d}~ww xY w)a  
        Fetches the raw inventory report configuration from GCS based on the
        specified location and ID.

        Parameters:
            gcs_file_system (GCSFileSystem): An instance of the 'GCSFileSystem'
            class (see 'core.py').
            location (str): The location of the inventory report in GCS.
            id (str): The ID of the inventory report in GCS.

        Returns:
            dict: A dictionary containing the raw inventory report
            configuration retrieved from GCS.

        Raises:
            Exception: If there is an error while fetching the inventory
            report configuration.
        z,{}/projects/{}/locations/{}/reportConfigs/{}GETT)json_outNz9Error encountered when fetching inventory report config: .)projectformatr   BASE_URL_call	Exceptionr'   )r   r	   r
   r,   urlr   es          r#   r   z2InventoryReport._fetch_raw_inventory_report_config   s      & ")<jj17HbII	0?0E0EsT 1F 1 1 + + + + + +' /. 	 	 	PAPPP  	s   A 
A1A,,A1c           	         |                      d          }t                              |                     d                    }t                              |                     d                    }|                      d          }|                     d          }|                      d          }|                     d          }|                     d          }	|                     d	          }
t          j                    }||k     s||k    rt          d
| d| d| d          |
                    d          }|r4	 |
                    d           n# t
          $ r t          d          w xY wt          |||	|
|          }|S )a  
        Parses the raw inventory report configuration and validates its properties.

        Parameters:
            raw_inventory_report_config (dict): A dictionary containing the raw
            inventory report configuration retrieved from GCS.
            use_snapshot_listing (bool): A flag indicating whether to use snapshot
            listing in the inventory report.

        Returns:
            InventoryReportConfig: An instance of the InventoryReportConfig
            class representing the parsed inventory report configuration.

        Raises:
            ValueError: If the current date is outside the start and
            end range specified in the inventory report config.
            ValueError: If the "name" field is not present in the metadata
            fields of the report config.
            ValueError: If "size" field is not present in the metadata
            fields and use_snapshot_listing is True.
        frequencyOptions	startDateendDateobjectMetadataReportOptionsstorageDestinationOptions
csvOptionsr   destinationPathmetadataFieldszCurrent date z& is outside the range                 z and z* specified by the inventory report config.namesizezIf you want to use the snapshot for listing, the object size                         metadata has to be included in the inventory report.csv_optionsr   destination_pathmetadata_fieldsobj_name_idx)r   r   _convert_obj_to_dater   nowr'   indexInventoryReportConfig)r   r   frequency_options
start_dateend_dateobject_metadata_report_optionsstorage_destination_optionsr?   r   r@   rA   todayrB   r   s                 r#   r   z2InventoryReport._parse_raw_inventory_report_config   s   2 8;;<NOO$99!!+..
 

 #77!!),,
 
 *E)H)H)*
 *
& 'E&H&H''
 '
#
 255lCC,00::6::;LMM8<<=MNN :!1!1W W WW W"*W W W   ',,V44   	%%f----    N   #8#-+%#
 #
 #
 '&s   >E E.c                   K   g }|j         }|j        }|                     dd||d           d{V }|                    |                    dg                      |                    dd          }|b|                     dd||d|           d{V }|                    |                    dg                      |                    dd          }|bt          |          d	k    rt          d
          |S )a  
        Fetches all inventory report metadata from GCS based on the specified
        inventory report config.

        Parameters:
            gcs_file_system (GCSFileSystem): An instance of the 'GCSFileSystem'
            class (see 'core.py').
            inventory_report_config (InventoryReportConfig): An instance of
            the InventoryReportConfig class representing the inventory report
            configuration.

        Returns:
            list: A list containing dictionaries representing the metadata of
            objects from the inventory reports.

        Raises:
            ValueError: If the fetched inventory reports are empty.
        r)   zb/{}/oT)r   r*   NitemsnextPageToken)r   r*   	pageTokenr   zbNo inventory reports to fetch. Check if                 your inventory report is set up correctly.)r   r@   r/   extendr   lenr'   )r   r   r   r   r@   pagenext_page_tokens          r#   r   z0InventoryReport._fetch_inventory_report_metadata  sd     , %'! )/2C %**8V,<t + 
 
 
 
 
 
 
 
 	"(('2)>)>???((?D99 )(..') /        D &,,TXXgr-B-BCCC"hh==O ) ())Q..<  
 )(r%   c                 (    t          | d d          S )a  
        Sorts the inventory report metadata based on the 'timeCreated' field
        in reverse chronological order.

        Parameters:
            unsorted_inventory_report_metadata (list): A list of dictionaries
            representing the metadata of objects from the inventory reports.

        Returns:
            list: A sorted list of dictionaries representing the inventory
            report metadata, sorted in reverse chronological order based
            on 'timeCreated'.
        c                 \    t                               |                     d                    S )NtimeCreated)r   _convert_str_to_datetimer   )irs    r#   <lambda>zAInventoryReport._sort_inventory_report_metadata.<locals>.<lambda>i  s%    ?CC}%%  r%   T)keyreverse)sortedr   s    r#   r   z/InventoryReport._sort_inventory_report_metadataY  s-     .  
 
 
 	
r%   c           	        K   |d         }t                               |                    d                                                    }g }|D ]}t                               |d                                                   }||k    r_|                     dd||                    d          d           d{V \  }}	|	                                }
|                    |
           |S )	ax  
        Downloads the most recent inventory report content from GCS based on
        the inventory report metadata.

        Parameters:
            gcs_file_system (GCSFileSystem): An instance of the 'GCSFileSystem'
            class (see 'core.py').
            inventory_report_metadata (list): A list of dictionaries
            representing the metadata of objects from the inventory reports.
            bucket (str): The name of the GCS bucket containing
            the inventory reports.

        Returns:
            list: A list containing the content of the most recent inventory
            report as strings.
        r   rW   r)   z	b/{}/o/{}r<   media)altN)r   rX   r   dater/   decodeappend)r   r   r   most_recent_inventory_reportmost_recent_dater   metadatainventory_report_date_headerencoded_contentdecoded_contents              r#   r   z2InventoryReport._download_inventory_report_contento  s     ( (A'C$*CC(,,];;
 

$&& 	 $&  2 	A 	AH$3$L$L'% %dff " %(888 2A1F1F;V0D0D' 2G 2 2 , , , , , ,(
 #2"8"8":":(//@@@''r%   c           
      \   |j         }|                    dd          }|                    dd          }|                    dd          }g }	|D ]]}
|
                    |          }|r
|dd         }|D ]7}t                              ||| |||	          }|	                    |           8^|	S )
a  
        Parses the raw inventory report content and extracts object details.

        Parameters:
            gcs_file_system (GCSFileSystem): An instance of the 'GCSFileSystem'
            class (see 'core.py').
            inventory_report_content (list): A list of strings containing the
            raw content of the inventory report.
            inventory_report_config (InventoryReportConfig): An instance of the
            InventoryReportConfig class representing the inventory report
            configuration.
            use_snapshot_listing (bool): A flag indicating whether to use snapshot
            listing in the inventory report.
            bucket (str): The name of the GCS bucket containing the inventory
            reports.

        Returns:
            list: A list of dictionaries representing object details parsed
            from the inventory report content.
        recordSeparator
	delimiter,headerRequiredF   N)inventory_report_liner   r   r   rn   r   )r?   r   splitr   _parse_inventory_report_linerc   )r   r   r   r   r   r?   record_separatorrn   header_requiredr   contentlineslineobjs                 r#   r   z/InventoryReport._parse_inventory_report_content  s    8 .9&??+<dCCOOK55	%//*:EBB/ 	$ 	$GMM"233E  "abb	  
$ 
$%BB*.)=$3,C'! C   s####
$ r%   c           	      0   |j         }|j        }|du rT|                    d t          ||                                                     |                    D             |          }n/d|                                                     |          |         i}|S )a  
        Parses a single line of the inventory report and extracts object details.

        Parameters:
            inventory_report_line (str): A string representing a single line of
            the raw content from the inventory report.
            use_snapshot_listing (bool): A flag indicating whether to use snapshot
            listing in the inventory report.
            gcs_file_system (GCSFileSystem): An instance of the 'GCSFileSystem'
            class (see 'core.py').
            inventory_report_config (InventoryReportConfig): An instance of the
            InventoryReportConfig class representing the inventory report
            configuration.
            delimiter (str): The delimiter used in the inventory report content
            to separate fields.
            bucket (str): The name of the GCS bucket containing the inventory
            reports.

        Returns:
            dict: A dictionary representing object details parsed from the
            inventory report line.
        Tc                     i | ]\  }}||	S  r}   ).0r[   values      r#   
<dictcomp>z@InventoryReport._parse_inventory_report_line.<locals>.<dictcomp>  s.       "U   r%   r<   )rB   rA   _process_objectzipstriprs   )	rr   r   r   r   rn   r   rB   rA   rz   s	            r#   rt   z,InventoryReport._parse_inventory_report_line  s    < /;1A
  4''!11 &)')>)D)D)F)F)L)LY)W)W' '    CC 06688>>yII,WXC
r%   c                     d|du rfd| D             g fS g }t                      }| D ]}|                    d          }|                              s-|t                    d         }|                    d          }|dk    r|                    |           u|d|         }	                    d          dk    rdndz   |	z   |	dk    rdndz   }
|                    |
           |t          |          fS )aA  
        Constructs the final snapshot based on the retrieved objects and prefix.

        Parameters:
            objects (list): A list of dictionaries representing object details
            from the inventory report.
            prefix (str): A prefix used to filter objects in the snapshot based
            on their names.
            use_snapshot_listing (bool): A flag indicating whether to use snapshot
            listing in the inventory report.

        Returns:
            tuple: A tuple containing two lists: the 'items' list representing
            object details for the snapshot, and the 'prefixes' list containing
            subdirectory prefixes. If 'use_snapshot_listing' is set to False,
            'prefix' will also be empty, and 'items' will contains the object
            names in the snapshot.
        N Fc                 d    g | ],}|                     d                                         *|-S )r<   )r   
startswith)r~   rz   r   s     r#   
<listcomp>z=InventoryReport._construct_final_snapshot.<locals>.<listcomp>)  s6    QQQCcggfoo.H.H.P.PQCQQQr%   r<   /)	setr   r   rR   findrc   rstripaddlist)r   r   r   rN   prefixesrz   obj_nameobject_name_no_prefixfirst_delimiter_idxdir
obj_prefixs    `         r#   r   z)InventoryReport._construct_final_snapshot  sU   & >F  5((QQQQ7QQQSUUU
 EuuH ) )776??
  **622  )1V(?% '<&@&@&E&E# '",,LL%%% ,,@-@,@AMM#&&#r\\rrs4 !BYYrrC1  Z((((d8nn$$r%   c                 T    | d         }| d         }| d         }t          |||          S )a:  
        Converts a dictionary representing a date object to a datetime object.

        Parameters:
            obj (dict): A dictionary representing a date object with keys "day",
            "month", and "year".

        Returns:
            datetime: A datetime object representing the converted date.
        daymonthyearr   )rz   r   r   r   s       r#   rC   z$InventoryReport._convert_obj_to_dateR  s1     %jG6{eS)))r%   c                 R    t          j        |                     dd                    S )a8  
        Converts an ISO-formatted date string to a datetime object.

        Parameters:
            date_string (str): An ISO-formatted date string with or without
            timezone information (Z).

        Returns:
            datetime: A datetime object representing the converted date and time.
        Zz+00:00)r   fromisoformatreplace)strs    r#   rX   z(InventoryReport._convert_str_to_datetimec  s#     %ckk#x&@&@AAAr%   N)__name__
__module____qualname____doc__r.   classmethodr$   r   r   r   r   r   r   r   rt   r   staticmethodrC   rX   r}   r%   r#   r   r      s       8 8v ;HL L [L\G G G0  @N' N' N'`>) >) >)@
 
 
,2( 2( 2(h8 8 8t1 1 1f@% @% @%D * * \*  B B \B B Br%   r   c                       e Zd ZdZd ZdS )rF   a  
    Represents the configuration for fetching inventory reports.

    Attributes:
        csv_options (dict): A dictionary containing options for parsing CSV
        format in the inventory reports.
        bucket (str): The name of the GCS bucket from which to fetch the
        inventory reports.
        destination_path (str): The path within the GCS bucket where the
        inventory reports are stored.
        metadata_fields (list): A list of strings representing metadata
        fields to be extracted from the inventory reports.
        obj_name_idx (int): The index of the "name" field in the 'metadata_fields'
        list, used to identify object names.
    c                 L    || _         || _        || _        || _        || _        d S )Nr>   )selfr?   r   r@   rA   rB   s         r#   __init__zInventoryReportConfig.__init__  s1     ' 0.(r%   N)r   r   r   r   r   r}   r%   r#   rF   rF   r  s-          ) ) ) ) )r%   rF   N)r   r   objectrF   r}   r%   r#   <module>r      s         k	B k	B k	B k	B k	B k	B k	B k	B\) ) ) ) )F ) ) ) ) )r%   