
    pѬiJ                         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  \R                  " S5      r
 " S S5      rSqS rg)	aM  
Google Drive Health Connect connector.

Searches Bill's Google Drive for Health Connect zip files,
downloads the latest one to a temp directory, and hands it
off to the health_connect parser for ingestion.

Primary method: Google Drive API (no dependency on local sync)
Fallback: filesystem watcher (local Google Drive sync folder)
    N)datetime	timedelta)Pathzgdrive-healthc                   f    \ rS rSrSrS r\S 5       r\S 5       rSS jr	SS jr
SS	 jrSS
 jrSrg)GDriveHealthConnector   z=Search and download Health Connect exports from Google Drive.c                     S U l         S U l        [        [        R                  " 5       5      S-  U l        U R
                  R                  SS9  g )Nzclawd-health-downloadsT)exist_ok)_service
_availabler   tempfile
gettempdir_download_dirmkdirselfs    4/Users/bsyrros/clawd/whatsapp-agent/gdrive_health.py__init__GDriveHealthConnector.__init__   sC    !("5"5"78;SS  $ /    c                     U R                   c   SSKJn  U" 5       U l         U R                   SLa  U R                   $ S$ ! [         a)  n[        R                  SU 35        SU l          SnANKSnAff = f)zLazy-load Drive service.Nr   )build_drive_servicez"Google Drive service unavailable: F)r   google_authr   	Exceptionloggerwarning)r   r   es      r   serviceGDriveHealthConnector.service   sk     == &; 3 5 !%U :t}}DD  &!CA3GH %&s   > 
A1A,,A1c                     U R                   cZ  U R                  SLU l         U R                   (       a!  [        R                  S5        U R                   $ [        R                  S5        U R                   $ )z'Check if Google Drive API is available.NzGoogle Drive connector: ACTIVEz=Google Drive connector: INACTIVE (falling back to filesystem))r   r   r   infor   s    r   	availableGDriveHealthConnector.available+   sW     ??""ll$6DO<=  [\r   c                 6   U R                   (       d  / $  / SQn0 nU Hm  n SU S3nU R                  R                  5       R                  USSSS9R	                  5       nUR                  S/ 5       H  nUS	   U;  d  M  XsUS	   '   M     Mo     U(       d  [        R                  S5        / $ [        R                  " 5       [        US9-
  n	/ n
UR                  5        Hy  n [        R                  " US   R                  SS5      5      R                  SS9nX:  a:  U
R                  US	   US   US   [!        UR                  SS5      5      S.5        My  M{     U
R'                  S SS9  U
(       a+  [        R)                  S[+        U
5       SU
S   S    S35        U
$ ! [         a'  n[        R                  S
U SU 35         SnAGM  SnAff = f! ["        [$        4 a     GM
  f = f! [         a#  n[        R-                  SU 3SS9  / s SnA$ SnAff = f)z
Search Google Drive for Health Connect zip files.

Returns list of dicts: [{id, name, modifiedTime, size}, ...]
sorted by modifiedTime descending (newest first).
)z?name contains 'Health Connect' and mimeType = 'application/zip'z?name contains 'health_connect' and mimeType = 'application/zip'z7name contains 'Health Connect' and name contains '.zip'z7name contains 'health_connect' and name contains '.zip'(z) and trashed = falsez-files(id, name, modifiedTime, size, mimeType)zmodifiedTime desc
   )qfieldsorderBypageSizefilesidzDrive query failed: u    — Nz-No Health Connect files found in Google Drive)hoursmodifiedTimeZz+00:00)tzinfonamesizer   )r,   r1   r.   r2   c                     U S   $ )Nr.    )xs    r   <lambda>CGDriveHealthConnector.search_health_connect_files.<locals>.<lambda>t   s	    An,=r   T)keyreversezFound z* Health Connect file(s) in Drive (newest: )zDrive search failed: exc_info)r"   r   r+   listexecutegetr   r   debugr   utcnowr   valuesfromisoformatreplaceappendint
ValueErrorKeyErrorsortr!   lenerror)r   max_age_hoursqueries	all_filesquery
full_queryresultsfr   cutoffrecent_filesmod_times               r   search_health_connect_files1GDriveHealthConnector.search_health_connect_files6   s?    ~~I@	G I #$UG+@!AJ"ll00277$N 3!#	 8 
 gi  %[["5T7)312ag. 6 !$ LM	 __&)GGFL%%''55.)11#x@ gTg*   )$++"#D'$%fI,-n,=$'fa(8$9	-  * (  "=tLS./ 0  ,Q 78;
  G ! LL#7weA3!GH. #H-   	LL04tLDI	sy   G+ AF?F
!G+ ,4G+ !A3GA
G+ 
G)GG+ GG+ G(#G+ 'G((G+ +
H5HHHNc                    U R                   (       d  g SSKJn  U(       d;  U R                  R	                  5       R                  USS9R                  5       nUS   nU R                  U-  nUR                  5       (       aj  [        R                  " 5       R                  5       UR                  5       R                  -
  S-  nUS:  a#  [        R                  SU 35        [!        U5      $ U R                  R	                  5       R#                  US	9n[$        R&                  " 5       nU" X5      n	S
n
U
(       dU  U	R)                  5       u  pU(       a3  [        R+                  S[-        UR/                  5       S-  5       S35        U
(       d  MU  [1        US5       nUR3                  UR5                  5       5        SSS5        UR                  5       R6                  S-  n[        R                  SU SUS S35        [!        U5      $ ! , (       d  f       NS= f! [8         a!  n[        R;                  SU 3SS9   SnAgSnAff = f)zV
Download a file from Google Drive by ID.
Returns local file path or None on failure.
Nr   )MediaIoBaseDownloadr1   )fileIdr(   i     zUsing cached download: )rZ   FzDownload progress: d   %wbi   zDownloaded:  (z.0fz KB)zDrive download failed: Tr;   )r"   googleapiclient.httprY   r   r+   r?   r>   r   existsr   now	timestampstatst_mtimer   r!   str	get_mediaioBytesIO
next_chunkr@   rF   progressopenwritegetvaluest_sizer   rK   )r   file_idfilenamerY   meta
local_path	age_hoursrequestbuffer
downloaderdonestatusrR   size_kbr   s                  r   download_file#GDriveHealthConnector.download_file   s   
 ~~*	@ ||))+//"6 0 ')   <++h6J   ""LLN,,.1B1K1KK	 q=KK"9* FGz?* ll((*44G4DGZZ\F,V=JD)446LL#6s6??;Ls;R7S6TTU!VW d j$'1)* ( !oo'//$6GKK,xj73-tDEz?" ('  	LL21#6LF	s>   CH *B H H  H8AH 
HH 
I H<<Ic                     U R                  US9nU(       d  gUS   nUS   S:  a#  [        R                  SUS    SUS    S	35        gU R                  US
   US   5      $ )z
Find and download the latest Health Connect file from Drive.

Returns local file path or None.
This is the main entry point for the scheduler.
)rL   Nr   r2   i  zSkipping small file: r1   r_   z bytes)r,   )rV   r   r   r{   )r   rL   r+   latests       r   fetch_latest_health_connect1GDriveHealthConnector.fetch_latest_health_connect   s|     00}0Mq &>J&NN'v'7r&.9IQ !!&,v??r   c                     [         R                  " 5       R                  5       US-  -
  nU R                  R	                  5        HU  nUR                  5       R                  U:  d  M#  UR                  5         [        R                  SUR                   35        MW     g! [         a"  n[        R                  SU 35         SnAgSnAff = f)z*Remove downloaded files older than N days.iQ zCleaned up old download: zCleanup failed: N)r   rb   rc   r   iterdirrd   re   unlinkr   r@   r1   r   r   )r   max_age_daysrS   rR   r   s        r   cleanup_old_downloads+GDriveHealthConnector.cleanup_old_downloads   s    	3\\^--/<%3GHF''//1668$$v-HHJLL#<QVVH!EF 2  	3NN-aS122	3s   A"B (6B 
C)CC)r   r   r   )0   )N)   )   )__name__
__module____qualname____firstlineno____doc__r   propertyr   r"   rV   r{   r   r   __static_attributes__r4   r   r   r   r      sL    G0 	E 	E  JX2h@,	3r   r   c                  0    [         c
  [        5       q [         $ )z(Get the singleton GDriveHealthConnector.)
_connectorr   r4   r   r   get_connectorr      s     *,
r   )r   osrh   r   loggingr   r   pathlibr   	getLoggerr   r   r   r   r4   r   r   <module>r      sG   	 
 	   ( 			?	+3 3F 
r   