
    zTjV/                        d Z ddlmZ ddlZddlZddlZddlmZ  ee      j                         j                  j                  Zedz  Zedz  ZdgZddZdd	Zdd
Zd ZddZd Zy)u  Shared Google Drive storage — in-process MCP so Jarvis (and any AI on the
same credentials) can read/write/upload/remove files from one shared folder.

This is the storage twin of the shared MEMORY: a single "Jarvis Drive" folder on
Ahmed's Google account that every Jarvis instance / Claude can use to pass files
around (a CRM export, a doc, a screenshot, notes).

AUTH = SERVICE ACCOUNT (key in jarvis_drive_sa.json), NOT a user login. A service
account has no Drive of its own, so it can ONLY see the folders Ahmed explicitly
SHARES with it — the one "Jarvis Drive" folder. His personal Drive is not merely
code-blocked, it is structurally invisible: the SA cannot list or reach it at all.
The key also works on any machine (no per-user login, no token expiry), so this
is genuinely shared across devices. MCP_DRIVE=0 disables the whole server.

Tools (Claude sees them as mcp__drive__<name>):
  drive_list      list files in the shared folder
  drive_read      read a text file's contents (by name or id)
  drive_write     create/overwrite a text file from given content
  drive_upload    upload a local file into the folder
  drive_download  download a folder file to a local path
  drive_delete    remove (trash) a file (by name or id)
    )annotationsN)Pathzjarvis_drive_sa.jsonzjarvis_drive_folder.txtz%https://www.googleapis.com/auth/drivec                 r    t         j                  j                  dd      dk(  ryt        j	                         S )zHOn when the service-account key exists and it isn't explicitly disabled.	MCP_DRIVE10F)osenvironget_SA_KEYexists     A/Users/ahmed/devFolder/Ultron/claude-voice/voice/drive_control.pyenabledr   '   s)    	zz~~k3'3.>>r   c                    dd| dgiS )Ncontenttext)typer   r   )msgs    r   _textr   .   s    5677r   c                 F    t         j                         j                         S )N)_FOLDER_FILE	read_textstripr   r   r   
_folder_idr   2   s    !!#))++r   c                     ddl m}  ddlm} | j                  j                  t        t              t              } |dd|d      S )	zBuild a Drive v3 client authenticated as the service account. The SA can
    only reach folders shared with it, so this can never touch Ahmed's own files.r   )service_account)build)scopesdrivev3F)credentialscache_discovery)	google.oauth2r   googleapiclient.discoveryr   Credentialsfrom_service_account_filestrr   _SCOPES)r   r   credss      r   _servicer,   6   s@     ./''AAGW B &E$E5IIr   c                   t        |      j                         }|syt               }	 | j                         j	                  |d      j                         }||j	                  d      xs g v r|S dS # t        $ r Y nw xY wd| d| d}| j                         j                  |dd	      j                         j	                  d
g       }|r|d   S dS )uR  Find a file by id or name — but ONLY inside the Jarvis Drive folder.
    This is the code jail: with the full-Drive token, a bare id could point at
    any file in Ahmed's Drive, so we REFUSE anything whose parent isn't our
    folder. Every read/write/delete goes through here, so nothing outside the
    shared folder is ever touched.Nzid,name,mimeType,size,parents)fileIdfieldsparents'z)' in parents and trashed=false and name='r!   zfiles(id,name,mimeType,size))qspacesr/   filesr   )r)   r   r   r4   r   execute	Exceptionlist)svc
name_or_idreffidfr2   r4   s          r   _resolver=   @   s     j/


!C
,CIIKOO>  @@G	 	
AEE),23q== SE:3%q	AAIIKq#A  %giGR(8 
 58&$&s   AA2 0A2 2	A>=A>c            
       	
 dd l 
ddlm} m} ddlmm	  | ddi       d
fd       } | ddd	t        i      d
fd
       } | ddt        t        d      d	
fd       } | ddt        t        d      d
fd       } | ddt        t        d      d
fd       } | ddd	t        i      d
fd       } |dd||||||g      S )Nr   )toolcreate_sdk_mcp_server)MediaFileUploadMediaIoBaseUpload
drive_listzList the files in the shared Jarvis Drive folder (name, type, size, last modified). Use for 'what's in the drive/storage', 'list my shared files', 'what did I save there'.c                  K   d }	 j                  |       d {   }|st        d      S g }|D ]R  }|j                  d      }|rt        |      dz   dnd}|j	                  d|d    d	| d
|d   d d  d|d    d	       T t        t        |       ddj                  |      z         S 7 # t        $ r$}t        dt        |      d d        cY d }~S d }~ww xY ww)Nc                     t               } dt                d}| j                         j                  |ddd      j	                         j                  dg       }|S )Nr1   z' in parents and trashed=falser!   zmodifiedTime descz)files(id,name,mimeType,size,modifiedTime))r2   r3   orderByr/   r4   )r,   r   r4   r7   r5   r   )r8   r2   r4   s      r   workz.build_server.<locals>.drive_list.<locals>.workb   s^    *CJL>!?@AIIK$$G-@B %  ')CC,  Lr   z!The shared Drive folder is empty.sizei   KBu   —z- namez  (z, modifiedTime
   z) [id id]z file(s) in Jarvis Drive:

zdrive_list failed:    )		to_threadr   r   intappendlenjoinr6   r)   )argsrG   r4   linesr<   szeasyncios          r   rC   z build_server.<locals>.drive_list]   s    
		?!++D11E@AAEUU6]-/Bb)Ur!F)Ct2a6G6L5M N$$%dG9A/ 0 
 CJ<'BC99U+, - - 2  	?.s1vds|n=>>	?sO   C"B2 B0B2 C"BB2 /C"0B2 2	C;CCC"CC"
drive_readzRead a text file's contents from the shared folder. `file` = the file name or its id. Works for plain text / csv / json / markdown and Google Docs (exported as text).filec                &   K    fd}	 j                  |       d {   \  }}|t        d      S |d d t        |      dkD  rdndz   }t        |d    d|       S 7 ?# t        $ r$}t        dt	        |      d d	        cY d }~S d }~ww xY ww)
Nc                    t               } t        | j                  dd            }|sy|j                  dd      }|j                  d      r3| j	                         j                  |d   d      j                         }n1| j	                         j                  |d   	      j                         }|t        |t              r|j                  d
d      fS t        |      fS )Nr\    )Nz	not foundmimeTypezapplication/vnd.google-appsrM   
text/plain)r.   r`   r.   utf-8ignore)r,   r=   r   
startswithr4   exportr5   	get_media
isinstancebytesdecoder)   )r8   r<   mimedatarV   s       r   rG   z.build_server.<locals>.drive_read.<locals>.work~   s    *Cdhhvr23A(55R(D<=yy{))T7\ * ;;B79  yy{,,AdG,<DDF$T51 {{7H5 B B7:4yB Br   z.drive_read: no such file in the shared folder.ip  u    …[truncated]r_   rJ   z:
zdrive_read failed: rP   )rQ   r   rT   r6   r)   )rV   rG   r<   bodysniprY   rZ   s   `     r   r[   z build_server.<locals>.drive_ready   s     
	B	?#--d33GAtyMNN;s4y47G"3RPDAfI;c$011	 4
  	?.s1vds|n=>>	?sN   BA! AA! B*A! BA! !	B*B	BB	BBdrive_writea  Create (or overwrite) a text file in the shared folder from content you provide. `name` = the file name (e.g. 'riyadh-leads.csv'), `content` = the full text to store. Use to hand a file to another AI/device, e.g. write a CRM or notes for Jarvis to pick up later.)rJ   r   c                  K   t        | j                  dd            j                         t        | j                  dd            st        d      S fd}	 j	                  |       d {   \  }}t        | d d| d      S 7 # t
        $ r$}t        d	t        |      d d
        cY d }~S d }~ww xY ww)NrJ   r_   r   z%drive_write failed: need a file name.c                    t               } t        j                        d   xs d} t        j                  j                  d            |d      }t        |       }|rM|j                  d      k(  r9| j                         j                  |d   |      j                          d	|d   fS t               gd
}| j                         j                  ||d      j                         }d|d   fS )Nr   ra   rc   Fmimetype	resumablerJ   rM   r.   
media_bodyupdatedrJ   r0   rm   rv   r/   created)r,   	mimetypes
guess_typeioBytesIOencoder=   r   r4   updater5   r   create)	r8   rk   mediaexistingmetaoutrB   r   rJ   s	         r   rG   z/build_server.<locals>.drive_write.<locals>.work   s    *C''-a0@LD%

7>>'23d!E  T*HHLL0D8		""(4.U" %%,WY (4.00 jl^<D))+$$$5$ ''.wy c$i''r    z in Jarvis Drive (id ).zdrive_write failed: rP   )r)   r   r   r   rQ   r6   )	rV   rG   verbr;   rY   r   rJ   rB   rZ   s	        @@r   ro   z!build_server.<locals>.drive_write   s      488FB'(..0dhhy"-.@AA	(	@%//55ID#D64&(=cU"EFF 6 	@/At~>??	@sH   ACB 3B4B CB 	B>B93B>4C9B>>Cdrive_uploadzUpload a LOCAL file (by path on this Mac) into the shared folder. `local_path` = absolute path; `name` = optional name to store it as (defaults to the file's own name). Use for 'put this file on the drive', 'upload X to storage'.)
local_pathrJ   c                d  K   t         j                  j                  t        | j	                  dd            j                               rt         j                  j                        st        dd      S t        | j	                  dd            j                         xs t         j                  j                        fd}	 j                  |       d {   \  }}t        | d d| d	      S 7 # t        $ r$}t        d
t        |      d d        cY d }~S d }~ww xY ww)Nr   r_   z drive_upload failed: no file at .rJ   c                    t               } t        j                        d   xs d} |d      }t        |       }|rM|j	                  d      k(  r9| j                         j                  |d   |      j                          d|d   fS t               gd	}| j                         j                  ||d
      j                         }d|d   fS )Nr   zapplication/octet-streamTrr   rJ   rM   ru   rw   rx   ry   uploaded)
r,   r{   r|   r=   r   r4   r   r5   r   r   )	r8   rk   r   r   r   r   rA   lprJ   s	         r   rG   z0build_server.<locals>.drive_upload.<locals>.work   s    *C''+A.L2LD#BFET*HHLL0D8		""(4.U" %%,WY (4.00 jl^<D))+$$$5$ ''.wy s4y((r   r   z to Jarvis Drive (id r   zdrive_upload failed: rP   )r	   path
expanduserr)   r   r   isfiler   basenamerQ   r6   )	rV   rG   r   r;   rY   r   rJ   rA   rZ   s	        @@r   r   z"build_server.<locals>.drive_upload   s     WWDHH\2$> ? E E GH+;B6CDD488FB'(..0HBGG4D4DR4H	)	A%//55ID#D64&(=cU"EFF 6 	A0Q?@@	AsH   CD0D  "C>#D  =D0>D   	D-	D("D-#D0(D--D0drive_downloadzDownload a file from the shared folder to a LOCAL path on this Mac. `file` = name or id; `local_path` = where to save it. Use to pull a shared file down so a local tool (or Jarvis) can work with it.)r\   r   c                   K   t         j                  j                  t         j	                  dd            j                               st        d      S  fd}	 j                  |       d {   }|st        d      S t        d| d d      S 7 ## t        $ r$}t        d	t        |      d d
        cY d }~S d }~ww xY ww)Nr   r_   z)drive_download failed: need a local_path.c                 @   ddl m}  t               }t        |j	                  dd            }|sy t        j                  d      } | ||j                         j                  |d               }d}|s|j                         \  }}|s|j                          |d	   S )
Nr   )MediaIoBaseDownloadr\   r_   wbrM   rb   FrJ   )googleapiclient.httpr   r,   r=   r   r}   FileIOr4   rg   
next_chunkclose)	r   r8   r<   bufdldone_rV   dests	          r   rG   z2build_server.<locals>.drive_download.<locals>.work   s    @*Cdhhvr23A))D$'C$S#))+*?*?qw*?*OPBD--/4 IIKV9r   z2drive_download: no such file in the shared folder.zDownloaded u    → r   zdrive_download failed: rP   )	r	   r   r   r)   r   r   r   rQ   r6   )rV   rG   rJ   rY   r   rZ   s   `   @r   r   z$build_server.<locals>.drive_download   s      ww!!#dhh|R&@"A"G"G"IJDEE		C **400DQRR;tfE$q9:: 1  	C23q6$3<.ABB	CsT   AC
 B 4B5B C
B C
B 	C#C<C=C
CC
drive_deletezRemove (move to trash) a file from the shared folder. `file` = name or id. Use for 'delete X from the drive', 'remove that file'.c                    K    fd}	 j                  |       d {   }|st        d      S t        d| d      S 7  # t        $ r$}t        dt        |      d d        cY d }~S d }~ww xY ww)Nc                     t               } t        | j                  dd            }|sy | j                         j	                  |d   ddi      j                          |d   S )Nr\   r_   rM   trashedT)r.   rm   rJ   )r,   r=   r   r4   r   r5   )r8   r<   rV   s     r   rG   z0build_server.<locals>.drive_delete.<locals>.work   s\    *Cdhhvr23AIIKagY4EFNNPV9r   z0drive_delete: no such file in the shared folder.zDeleted z from Jarvis Drive.zdrive_delete failed: rP   )rQ   r   r6   r)   )rV   rG   rJ   rY   rZ   s   `   r   r   z"build_server.<locals>.drive_delete   s~     
		A **400DOPP8D6)<=>> 1  	A0Q?@@	AsM   A2A A A A2A A2 A 	A/A*$A/%A2*A//A2r!   z1.0.0)rJ   versiontools)rV   dictreturnr   )rZ   claude_agent_sdkr?   r@   r   rA   rB   r)   )r?   r@   rC   r[   ro   r   r   r   rA   rB   rZ   s           @@@r   build_serverr   X   s.   <G	,4579?	9?0 
,028#@?	@?. 
-K 3
')@)@6 
.+ c
*,A,A2 

K c
*	,
C,
C4 
.J3-A	A  !g:{L|- r   )r   bool)r   r)   r   r   )r   r)   )r9   r)   r   zdict | None)__doc__
__future__r   r}   r{   r	   pathlibr   __file__resolveparent_HEREr   r   r*   r   r   r   r,   r=   r   r   r   r   <module>r      sy   , # 	  	 X ''..
(
(00 3
38,J'0sr   