Ë
    ª«ëj¶"  ã                  ó„  — U d Z ddlmZ ddlZddl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  ej                  e«      ZdZded<   d	Zded
<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   g d¢Zd&d„Zd'd(d„Zd)d„Zd*d„Zd)d „Zd+d!„Z d'd,d"„Z!	 d'	 	 	 	 	 d-d#„Z"	 d'	 	 	 d,d$„Z#def	 	 	 	 	 d.d%„Z$y)/ac  Resolution of the unified ingest shared root and batch claiming.

Discovers and initializes a single shared folder used across devices
(Debian Mentem, virtual machine with CyberBrain26, Android phone, tablet
with local model container). The orchestrator claims files from inbox/
into processing/ batches and records everything in an append-only manifest.
é    )ÚannotationsN)ÚPath)Úuuid4ÚUNIFIED_INGEST_ROOTÚstrÚENV_SHARED_ROOTz~/UnifiedIngestÚDEFAULT_SHARED_ROOTz~/.config/syncthing/config.xmlÚSYNCTHING_CONFIGz~/.config/rclone/rclone.confÚRCLONE_CONFIG)ÚinboxÚ
processingÚsortedÚ
duplicatesÚindexÚtasksÚmanifestztuple[str, ...]ÚINGEST_SUBDIRSzingest-manifest.jsonlÚMANIFEST_FILENAMEé
   ÚintÚBATCH_LIMIT_MAX)	z.ssh/z.gnupg/z.password-store/z	auth.jsonzcredentials.jsonÚsecretÚtokenÚcredÚpasswordÚSENSITIVE_PATTERNS)z.keyz.pemz.kdbxÚSENSITIVE_EXTENSIONS)r   r	   r   r   r   r   r   r   r
   Úclaim_batchÚdetect_syncthing_foldersÚensure_shared_rootÚis_rclone_configuredÚis_sensitive_pathÚlist_mountpointsÚmanifest_pathÚmanifest_writeÚresolve_shared_rootc           	     óž   — t        t        j                  j                  t        j                  j	                  t        | «      «      «      «      S ©N)r   ÚosÚpathÚ
expandvarsÚ
expanduserr   )r*   s    úF/home/oem/CyberBrain26-unified/src/cyberbrain26/product/shared_root.pyÚ_expandr.   G   s/   € Ü”—‘×"Ñ"¤2§7¡7×#5Ñ#5´c¸$³iÓ#@ÓAÓBÐBó    c                ó¶  — | �t        | «      j                  «       S t        j                  j	                  t
        «      }|r7|j                  «       r't        |j                  «       «      j                  «       S t        «       D ]  }|c S  dD ]/  }t        |«      j                  «       }|j                  «       sŒ-|c S  t        t        «      j                  «       S )zéResolve the shared ingest root.

    Precedence: explicit argument > env UNIFIED_INGEST_ROOT >
    existing Syncthing folder > ~/Sync/ > ~/Documents/ > ~/Downloads/ >
    fallback ~/UnifiedIngest/. Does NOT create the directory.
    )z~/Sync/z~/Documents/z~/Downloads/)
r.   Úresolver)   ÚenvironÚgetr   Ústripr   Úexistsr	   )ÚexplicitÚ	env_valueÚfolderÚ	candidateÚps        r-   r&   r&   K   sµ   € ð ÐÜ�xÓ ×(Ñ(Ó*Ð*Ü—
‘
—‘œÓ/€IÙ�Y—_‘_Ô&Ü�y—‘Ó(Ó)×1Ñ1Ó3Ð3Ü*Ó,ò ˆØŠðà@ò ˆ	Ü�IÓ×&Ñ&Ó(ˆØ�8‰8�:ØŠHðô Ô&Ó'×/Ñ/Ó1Ð1r/   c                 ó|  — t        t        «      } | j                  «       sg S 	 | j                  dd¬«      }g }t        j                  d|«      D ]Z  }t        |j                  d«      «      j                  «       j                  «       }|j                  «       sŒJ|j                  |«       Œ\ |S # t        $ r g cY S w xY w)zEReturn paths of configured Syncthing folders (config existence only).úutf-8Úreplace©ÚencodingÚerrorsz<path>([^<]+)</path>é   )r.   r
   r5   Ú	read_textÚOSErrorÚreÚfinditerr   Úgroupr,   r1   Úappend)ÚcfgÚtextÚfoldersÚmatchr:   s        r-   r   r   `   sª   € ä
Ô"Ó
#€CØ�:‰:Œ<Øˆ	ðØ�}‰} g°iˆ}Ó@ˆð €GÜ—‘Ð4°dÓ;ò ˆÜ�—‘˜Q“Ó ×+Ñ+Ó-×5Ñ5Ó7ˆØ�8‰8�:Ø�N‰N˜1Õðð €Nøô ò ØŠ	ðús   £B- Â-B;Â:B;c                 ó<   — t        t        «      j                  «       S )z>Check whether rclone config exists (never runs rclone config).)r.   r   r5   © r/   r-   r!   r!   q   s   € ä”=Ó!×(Ñ(Ó*Ð*r/   c                 óÒ  — g } 	 t        ddd¬«      5 }|D ]Q  }|j                  «       }t        |«      dk\  sŒ"t        |d   «      }|j	                  «       sŒA| j                  |«       ŒS 	 ddd«       dD ]U  }t        |«      }|j                  «       sŒ|j                  «       D ]$  }|j                  «       sŒ| j                  |«       Œ& ŒW | S # 1 sw Y   ŒexY w# t        $ r Y Œsw xY w)	z9List candidate mount points (/proc/mounts, /mnt, /media).z/proc/mountsr<   r=   r>   é   rA   N)z/mntz/media)
ÚopenÚsplitÚlenr   Úis_absoluterG   rC   r5   ÚiterdirÚis_dir)ÚmountsÚfÚlineÚpartsr:   ÚbaseÚbpÚchilds           r-   r#   r#   v   sÝ   € à€Fð	Ü�.¨7¸9ÔEð 	)ÈØò )�ØŸ
™
›�Ü�u“: “?Ü˜U 1™X›�AØ—}‘}•ØŸ™ aÕ(ñ)÷	)ð #ò )ˆÜ�$‹ZˆØ�9‰9�;ØŸ™›ò )�Ø—<‘<•>Ø—M‘M %Õ(ñ)ð)ð €M÷	)ð 	)ûô ò Ùðús3   „C ’$C·CÁCÁ*C ÃCÃC Ã	C&Ã%C&c                ó”   — t        | «      j                  «       }t        D ]  }||v sŒ y t        D ]  }|j	                  |«      sŒ y y)z@Return True if path contains sensitive credentials/keys/secrets.TF)r   Úlowerr   r   Úendswith)r*   rI   ÚpatÚexts       r-   r"   r"   Œ   sP   € äˆt‹9�?‰?Ó€DÜ!ò ˆØ�$Š;Ùðô $ò ˆØ�=‰=˜ÕÙðð r/   c                ó€   — | r't        | «      j                  «       j                  «       n	t        «       }|dz  t        z  S )z)Return the path to ingest-manifest.jsonl.r   )r   r,   r1   r&   r   )Úshared_rootÚroots     r-   r$   r$   ˜   s7   € á7BŒ4�Ó×'Ñ'Ó)×1Ñ1Ô3ÔH[ÓH]€DØ�*ÑÔ0Ñ0Ð0r/   c                ó8  — t        |«      }|j                  j                  ddd¬«       t        j                  | ddd¬«      }t        |dd¬	«      5 }|j                  |d
z   «       ddd«       	 |j                  d«       y# 1 sw Y   ŒxY w# t        $ r Y yw xY w)zFAppend one JSON line to the manifest (mode 0o600). All paths relative.TéÀ  ©ÚparentsÚexist_okÚmode)ú,ú:F)Ú
separatorsÚensure_asciiÚ	allow_nanÚar<   )r?   ú
Né€  )	r$   ÚparentÚmkdirÚjsonÚdumpsrP   ÚwriteÚchmodrC   )Úentryrc   ÚmpathrX   rW   s        r-   r%   r%   ž   s“   € ô
 ˜+Ó&€EØ	‡L�L×Ñ˜t¨d¸ÐÔ?Ü�:‰:�e¨
ÀÐRWÔX€DÜ	ˆe�S 7Ô	+ð ¨qØ	�‰��t‘Ô÷ðØ�‰�EÕ÷ð ûô ò Ùðús   ÁBÁ/B ÂB
Â	BÂBc                ó˜  — | r't        | «      j                  «       j                  «       n	t        «       }|j	                  «       }|j                  ddd¬«       |s	 |j                  d«       t        D ]  }||z  j                  ddd¬«       Œ t        |«      }|j	                  «       s|j                  d¬«       |S # t        $ r Y Œ\w xY w)zBCreate the shared root and all ingest subdirectories (mode 0o700).Trf   rg   rr   )rj   )r   r,   r1   r&   r5   rt   rx   rC   r   r$   Útouch)rc   rd   ÚexistedÚsubrz   s        r-   r    r    ®   sÂ   € ñ 8CŒ4�Ó×'Ñ'Ó)×1Ñ1Ô3ÔH[ÓH]€DØ�k‰k‹m€GØ‡J�J�t d°€JÔ7Ùð	Ø�J‰J�uÔô ò DˆØ	�‰×Ñ 4°$¸UÐÕCðDô ˜$Ó€EØ�<‰<Œ>Ø�‰˜ˆÔØ€Køô ò 	Ùð	ús   ÁB= Â=	C	ÃC	c                ó¢  — | r't        | «      j                  «       j                  «       n	t        «       }|dz  }dt	        «       j
                  dd › �}|dz  |z  }|j                  ddd¬«       g }g }d	}|j                  «       �rt        |j                  «       «      D �]ù  }	||k\  r �nñ|	j                  «       sŒt        |	«      r²|j                  t        |	j                  |«      «      «       t        t	        «       j
                  |t!        j                   «       t        |	j                  |«      «      dd|	j#                  «       j$                  |	j&                  j)                  «       d
d
dddd	dœ|¬«       ŒÚt+        j,                  |	j/                  «       «      j1                  «       }
||	j2                  z  }	 |	j5                  |«       |j                  t        |j                  |«      «      «       t        t	        «       j
                  |t!        j                   «       t        |	j                  |«      «      t        |j                  |«      «      |
|j#                  «       j$                  |j&                  j)                  «       dddddd	dœ|¬«       |dz  }�Œü ||||dœS # t6        $ r"}t8        j;                  d|	|«       Y d}~�Œ*d}~ww xY w)zÑClaim up to `limit` files from inbox/ into processing/<batch_id>/.

    Returns a dict with batch_id, claimed (list of relative paths),
    skipped (list of sensitive paths), and manifest entries written.
    r   zb-Né   r   Trf   rg   r   ÚskippedÚorchestratorz
[REDACTED])ÚidÚbatch_idÚtsÚsrc_path_relÚdst_path_relÚsha256ÚsizeÚmime_or_extÚtypeÚstatusÚworkerÚreasonÚdup_of_sha256Ú	task_hits)rc   ÚotherÚclaimedrA   zCould not claim %s: %s)r„   r’   r�   Úcount)r   r,   r1   r&   r   Úhexrt   r5   r   rT   Úis_filer"   rG   r   Úrelative_tor%   ÚtimeÚstatÚst_sizeÚsuffixr^   Úhashlibrˆ   Ú
read_bytesÚ	hexdigestÚnamer=   rC   ÚloggerÚwarning)rc   Úlimitrd   r   r„   r   r’   r�   r“   ry   rˆ   ÚdstÚexcs                r-   r   r   Ã   sy  € ñ 8CŒ4�Ó×'Ñ'Ó)×1Ñ1Ô3ÔH[ÓH]€DØ�7‰N€EØ”E“G—K‘K  �OÐ$Ð%€HØ˜Ñ$ xÑ/€JØ×Ñ˜T¨D°uÐÔ=à€GØ€GØ€Eà‡|�|…~Ü˜EŸM™M›OÓ,ó 5	EˆEØ˜Š~ÚØ—=‘=”?ØÜ  Ô'Ø—‘œs 5×#4Ñ#4°TÓ#:Ó;Ô<Üä#›gŸk™kØ$,Ü"Ÿi™i›kÜ(+¨E×,=Ñ,=¸dÓ,CÓ(DØ(,Ø"&Ø %§
¡
£× 4Ñ 4Ø',§|¡|×'9Ñ'9Ó';Ø )Ø"+Ø"0Ø".Ø)-Ø%&ñð  !%õ#ð& Ü—^‘^ E×$4Ñ$4Ó$6Ó7×AÑAÓCˆFØ˜uŸz™zÑ)ˆCðEØ—‘˜cÔ"Ø—‘œs 3§?¡?°4Ó#8Ó9Ô:Üä#›gŸk™kØ$,Ü"Ÿi™i›kÜ(+¨E×,=Ñ,=¸dÓ,CÓ(DÜ(+¨C¯O©O¸DÓ,AÓ(BØ"(Ø #§¡£
× 2Ñ 2Ø'*§z¡z×'7Ñ'7Ó'9Ø 'Ø"+Ø"0Ø"&Ø)-Ø%&ñð  !%õ#ð& ˜‘
’ðg5	Eðp ØØØñ	ð øô ò EÜ—‘Ð7¸À×DÒDûðEús   Æ:CJ#Ê#	KÊ,K	Ë	K)r*   ú
str | PathÚreturnr   r(   )r6   ústr | Path | Noner¥   r   )r¥   z
list[Path])r¥   Úbool)r*   r¤   r¥   r§   )rc   r¦   r¥   r   )ry   Údictrc   r¦   r¥   ÚNone)rc   r¦   r¡   r   r¥   r¨   )%Ú__doc__Ú
__future__r   r›   ru   Úloggingr)   rD   r—   Úpathlibr   Úuuidr   Ú	getLoggerÚ__name__rŸ   r   Ú__annotations__r	   r
   r   r   r   r   r   r   Ú__all__r.   r&   r   r!   r#   r"   r$   r%   r    r   rM   r/   r-   ú<module>r³      s9  ðòõ #ã Û Û Û 	Û 	Û Ý Ý à	ˆ×	Ñ	˜8Ó	$€à,€�Ó ,Ø,Ð �SÓ ,à8Ð �#Ó 8Ø3€ˆsÓ 3ð#€�ó ð 1Ð �3Ó 0Ø€�Ó ð'Ð �Oó ð )BÐ �oÓ Aò€ó,Cô2ó*ó"+ó
ó,	ô1ð &*ðØðà"ðð 
óð" &*ðØ"ðà	óð, &*Ø ðPØ"ðPàðPð 
ôPr/   