
    *i*                        U d 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 ddl	m
Z
 ddlmZmZmZmZ ddlmZ  e
j                    dz  d	z  d
z  Zg dZdaed         ed<   g ddZde
defdZ G d d          ZdefdZddZdS )zpysonDB-backed metadata store for Raiden.

Collections (one JSON file each under ~/.config/raiden/db/):
  - demonstrations.json
  - teachers.json
  - tasks.json
  - calibration_results.json
  - camera_configs.json
    N)contextmanager)datetime)Path)Dict	GeneratorListOptional)getDbz.configraidendb)demonstrationsteacherstaskscalibration_resultscamera_configsRaidenDB	_instance   )datanextIdpathreturnc                    	 t          |           5 }t          j        |          }ddd           n# 1 swxY w Y   t          |t                    rd|vrt          d          dS # t          j        t
          t          f$ r t          t          j	                              }| 
                    d| d          }	 t          j        | |           t          d|j                    n# t          $ r Y nw xY wt          | d          5 }t          j        t           |d	
           ddd           n# 1 swxY w Y   t          d| j         d           Y dS w xY w)zwCheck *path* for valid JSON; if corrupt, back it up and reinitialize.

    Returns True if a repair was performed.
    Nr   zmissing 'data' keyFz.bak.jsonu"     [DB] Corrupt file backed up → w   )indentz  [DB] Reinitialized u    (data lost — see backup)T)openjsonload
isinstancedict
ValueErrorJSONDecodeErrorOSErrorinttimewith_suffixshutilcopy2printnamedump	_EMPTY_DB)r   fr   tsbackups        0/home/robot-lab/raiden_cmu/raiden/db/database.py_repair_filer3   $   s   
$ZZ 	 19Q<<D	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  $%% 	3t););1222u *g6   !!"2"2"2"233	Lv&&&Dv{DDEEEE 	 	 	D	$__ 	.Ii1----	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	.LdiLLLMMMttsu   A' 2A' 6A' 6+A' 'AE=,C*)E*
C74E6C77E
D3'E3D7	7E:D7	;EEc                   j   e Zd ZefdefdZeded         fd            Zd*dZ	de
defd	Zdee         fd
Zde
dee         fdZdede
ddfdZdeddfdZde
de
defdZdee         fdZde
dee         fdZdede
de
ddfdZdeddfdZdede
defdZdee         fdZdee         fdZdede
defdZdee         fdZdedede
ded ee         defd!Zdee         fd"Zdedee         fd#Z dedee         fd$Z!de
dee         fd%Z"d&edee         fd'Z#d&eddfd(Z$d&eddfd)Z%dS )+r   db_dirc                    |                     dd           || _        t          |dz            | _        t	          | j        d                                           t          j                    | _        t          D ]}t          || dz             t          t          |dz                      | _        t          t          |dz                      | _        t          t          |dz                      | _        t          t          |d	z                      | _        t          t          |d
z                      | _        d S )NT)parentsexist_okz.lockar   zdemonstrations.jsonzteachers.jsonz
tasks.jsonzcalibration_results.jsonzcamera_configs.json)mkdir_db_dirstr
_lock_pathr   close	threadingLock_mutex_COLLECTIONSr3   r
   r   r   r   r   r   )selfr5   r,   s      r2   __init__zRaidenDB.__init__?   s%   TD111fw.//T_c""((***n&& ! 	2 	2DT...01111#C1F(F$G$GHHc&?":;;<<3v45566
#(V6P-P)Q)Q#R#R #C1F(F$G$GHH    r   )NNNc              #     K   | j         5  t          | j        d          5 }t          j        |                                t          j                   	 dV  np# t          j        $ r^ t          D ]T}t          | j        | dz            }|r6t          | |t          t          | j        | dz                                 U w xY w	 t          j        |                                t          j                   n6# t          j        |                                t          j                   w xY w	 ddd           n# 1 swxY w Y   ddd           dS # 1 swxY w Y   dS )z:Acquire both in-process mutex and cross-process file lock.zr+Nr   )rA   r   r=   fcntlflockfilenoLOCK_EXr   r$   rB   r3   r;   setattrr
   r<   LOCK_UN)rC   lfr,   repaireds       r2   _lockzRaidenDB._lockR   s      [ 	< 	<dot,, <BIIKK777<EEEE+    !-  #/$~~~0M#N#N# # $ $ %c$,D*G&H&H I I  
   K		U];;;;EK		U];;;;;%< < < < < < < < < < < < < < <	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	<s_   E2D>AC;A-CC;	2D>;3D..D>2E>E	EE	EEENc                    |                                  5  t          D ]R}t          | j        | dz            r6t	          | |t          t          | j        | dz                                 S	 ddd           dS # 1 swxY w Y   dS )zGCheck and repair all collection files (call after detected corruption).r   N)rO   rB   r3   r;   rK   r
   r<   rC   r,   s     r2   repairzRaidenDB.repairj   s    ZZ\\ 	S 	S$ S S$~~~ =>> SD$c$,D2O.P.P(Q(QRRRS	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	Ss   AA>>BBr,   c                     |                                  5  | j                            |t          j                                                    d          cd d d            S # 1 swxY w Y   d S )N)r,   
created_at)rO   r   addr   now	isoformatrQ   s     r2   add_teacherzRaidenDB.add_teachers   s    ZZ\\ 	 	=$$X\^^-E-E-G-GHH 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   A A""A&)A&c                     |                                  5  | j                                        cd d d            S # 1 swxY w Y   d S NrO   r   getAllrC   s    r2   get_teacherszRaidenDB.get_teachersy   s    ZZ\\ 	* 	*=''))	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	*   ;??c                     |                                  5  | j                                        D ]}|d         |k    r|c cd d d            S 	 d d d            d S # 1 swxY w Y   d S Nr,   r[   rC   r,   ts      r2   get_teacher_by_namezRaidenDB.get_teacher_by_name}   s    ZZ\\ 	 	]))++  V9$$HH	 	 	 	 	 	 	 	$		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	   +AAA #A 
teacher_idc                     |                                  5  | j                            |d|i           d d d            d S # 1 swxY w Y   d S ra   )rO   r   
updateById)rC   rf   r,   s      r2   update_teacherzRaidenDB.update_teacher   s    ZZ\\ 	A 	AM$$Z&$@@@	A 	A 	A 	A 	A 	A 	A 	A 	A 	A 	A 	A 	A 	A 	A 	A 	A 	As   A  AAc                     |                                  5  | j                            |           d d d            d S # 1 swxY w Y   d S rZ   )rO   r   
deleteByIdrC   rf   s     r2   delete_teacherzRaidenDB.delete_teacher   s    ZZ\\ 	1 	1M$$Z000	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1   =AAinstructionc                     |                                  5  | j                            ||t          j                                                    d          cd d d            S # 1 swxY w Y   d S )N)r,   ro   rT   )rO   r   rU   r   rV   rW   )rC   r,   ro   s      r2   add_taskzRaidenDB.add_task   s    ZZ\\ 	 	:>> #."*,..":":"<"<  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	   AA##A'*A'c                     |                                  5  | j                                        cd d d            S # 1 swxY w Y   d S rZ   rO   r   r\   r]   s    r2   	get_taskszRaidenDB.get_tasks   s    ZZ\\ 	' 	':$$&&	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	'r_   c                     |                                  5  | j                                        D ]}|d         |k    r|c cd d d            S 	 d d d            d S # 1 swxY w Y   d S ra   rt   rb   s      r2   get_task_by_namezRaidenDB.get_task_by_name   s    ZZ\\ 	 	Z&&((  V9$$HH	 	 	 	 	 	 	 	$		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	re   task_idc                     |                                  5  | j                            |||d           d d d            d S # 1 swxY w Y   d S )N)r,   ro   )rO   r   rh   )rC   rx   r,   ro   s       r2   update_taskzRaidenDB.update_task   s    ZZ\\ 	W 	WJ!!'D+U+UVVV	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	Ws   AAAc                     |                                  5  | j                            |           d d d            d S # 1 swxY w Y   d S rZ   )rO   r   rk   rC   rx   s     r2   delete_taskzRaidenDB.delete_task   s    ZZ\\ 	+ 	+J!!'***	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+rn   r   output_filec                     |                                  5  | j                            ||t          j                                                    d          cd d d            S # 1 swxY w Y   d S )N)r~   r   rT   )rO   r   rU   r   rV   rW   )rC   r   r~   s      r2   add_calibration_resultzRaidenDB.add_calibration_result   s    ZZ\\ 	 	+//#. "*,..":":"<"<  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	rr   c                     |                                  5  | j                                        cd d d            S # 1 swxY w Y   d S rZ   rO   r   r\   r]   s    r2   get_calibration_resultsz RaidenDB.get_calibration_results   s    ZZ\\ 	5 	5+2244	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5r_   c                     |                                  5  | j                                        }|r|d         nd cd d d            S # 1 swxY w Y   d S )Nr   )rC   resultss     r2   get_latest_calibration_resultz&RaidenDB.get_latest_calibration_result   s    ZZ\\ 	4 	4.5577G")372;;t	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4s   %AAAconfig_filec                    t          j        |d          }|                                 5  | j                                        D ]F}t          j        |                    di           d          |k    r|d         c cddd           S G| j                            ||t          j                    	                                d          cddd           S # 1 swxY w Y   dS )zMSnapshot camera config into DB; reuse existing entry if content is unchanged.T)	sort_keysr   idN)r   r   rT   )
r   dumpsrO   r   r\   getrU   r   rV   rW   )rC   r   r   data_strcfgs        r2   snapshot_camera_configzRaidenDB.snapshot_camera_config   sA   :dd333ZZ\\ 
	 
	*1133 % %:cggfb11TBBBhNNt9$$
	 
	 
	 
	 
	 
	 
	 
	N&**#. "*,..":":"<"<  	
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	s   ACACC Cc                     |                                  5  | j                                        cd d d            S # 1 swxY w Y   d S rZ   )rO   r   r\   r]   s    r2   get_camera_configszRaidenDB.get_camera_configs       ZZ\\ 	0 	0&--//	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0r_   raw_data_pathcamera_config_idcalibration_result_idc                 6   |                                  5  | j                            dd|d d ||||t          j                                                    t          j                                                    d          cd d d            S # 1 swxY w Y   d S )NpendingF)status	convertedr   converted_data_paths3_data_pathrf   rx   r   r   rT   
updated_at)rO   r   rU   r   rV   rW   )rC   rf   rx   r   r   r   s         r2   add_demonstrationzRaidenDB.add_demonstration   s     ZZ\\ 	 	&**'!&%2+/$(",&(8-B"*,..":":"<"<"*,..":":"<"<  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   A,BBBc                     |                                  5  | j                                        cd d d            S # 1 swxY w Y   d S rZ   rO   r   r\   r]   s    r2   get_demonstrationszRaidenDB.get_demonstrations   r   r_   c                     |                                  5  fd| j                                        D             cd d d            S # 1 swxY w Y   d S )Nc                 F    g | ]}|                     d           k    |S )rf   r   ).0drf   s     r2   
<listcomp>z:RaidenDB.get_demonstrations_by_teacher.<locals>.<listcomp>   s:       55&&*44 444rE   r   rl   s    `r2   get_demonstrations_by_teacherz&RaidenDB.get_demonstrations_by_teacher   s    ZZ\\ 	 	   ,3355  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	   %AAAc                     |                                  5  fd| j                                        D             cd d d            S # 1 swxY w Y   d S )Nc                 F    g | ]}|                     d           k    |S )rx   r   )r   r   rx   s     r2   r   z7RaidenDB.get_demonstrations_by_task.<locals>.<listcomp>   s6       155;K;Kw;V;V;V;V;VrE   r   r|   s    `r2   get_demonstrations_by_taskz#RaidenDB.get_demonstrations_by_task   s    ZZ\\ 	 	   .5577  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	r   c                     |                                  5  | j                                        D ]+}|                    d          |k    r|c cd d d            S ,	 d d d            d S # 1 swxY w Y   d S )Nr   )rO   r   r\   r   )rC   r   r   s      r2   get_demonstration_by_raw_pathz&RaidenDB.get_demonstration_by_raw_path  s    ZZ\\ 	 	(//11  55))]::HH	 	 	 	 	 	 	 	:		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   8A)A))A-0A-demo_idc                     |                                  5  	 | j                            |          cd d d            S # t          $ r Y d d d            d S w xY w# 1 swxY w Y   d S rZ   )rO   r   getById	ExceptionrC   r   s     r2   get_demonstration_by_idz RaidenDB.get_demonstration_by_id	  s    ZZ\\ 	 	*227;;	 	 	 	 	 	 	 	    		 	 	 	 	 	 	 		 	 	 	 	 	 	 	 	 	s,   A=
AAAAA Ac                     t          j                                                    |d<   |                                 5  | j                            ||           d d d            d S # 1 swxY w Y   d S )Nr   )r   rV   rW   rO   r   rh   )rC   r   kwargss      r2   update_demonstrationzRaidenDB.update_demonstration  s    '|~~7799|ZZ\\ 	< 	<**7F;;;	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	<s   A&&A*-A*c                     |                                  5  | j                            |           d d d            d S # 1 swxY w Y   d S rZ   )rO   r   rk   r   s     r2   delete_demonstrationzRaidenDB.delete_demonstration  s    ZZ\\ 	4 	4**7333	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4rn   r   N)&__name__
__module____qualname___DB_DIRr   rD   r   r   rO   rR   r<   r&   rX   r   r   r^   r	   rd   ri   rm   rq   ru   rw   rz   r}   r   r   r   r   r   r   r   r   r   r   r   r   r    rE   r2   r   r   >   s       &- I It I I I I& <y!12 < < < ^<.S S S S     *d4j * * * *     A AC AD A A A A1 1 1 1 1 1S s s    '4: ' ' ' 'S Xd^    W3 Wc W W W W W W+3 +4 + + + +4 c c    5d 5 5 5 54x~ 4 4 4 44 c c    0DJ 0 0 0 0  	
   (} 
   20DJ 0 0 0 0 T
    # $t*    3 8D>    s x~    <C <d < < < <
4C 4D 4 4 4 4 4 4rE   c                  :    t           t                      a t           S rZ   )r   r   r   rE   r2   get_dbr     s    JJ	rE   c                  
    da dS )zForce the singleton to be recreated on next get_db() call.

    Useful after a detected corruption so the repaired files are reloaded.
    N)r   r   rE   r2   reset_dbr   !  s     IIIrE   r   )__doc__rG   r   r)   r?   r'   
contextlibr   r   pathlibr   typingr   r   r   r	   pysondbr
   homer   rB   r   __annotations__r.   boolr3   r   r   r   r   rE   r2   <module>r      s             % % % % % %             2 2 2 2 2 2 2 2 2 2 2 2      
$)++	
!H
,t
3   #'	8J & & &1%%	t     4Y4 Y4 Y4 Y4 Y4 Y4 Y4 Y4x         rE   