
    `gjI                       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mZmZm	Z	 ddl
mZ ddlmZ ddlmZ ddlmZmZ dd	lmZmZmZmZ dd
lmZ ddlmZ ddlmZmZ ddlm Z m!Z! ddl"m#Z#m$Z$ d'dZ%d(dZ&d Z'd)dZ(d*dZ)d+dZ*d,dZ+d-dZ,ddd	 	 	 	 	 	 	 	 	 d.dZ-d/dZ.d0dZ/d0dZ0d0dZ1d0dZ2d0d Z3d0d!Z4d0d"Z5d0d#Z6d0d$Z7d0d%Z8d0d&Z9y)1z3CLI commands for the Teams meeting pipeline plugin.    )annotationsN)datetime	timedeltatimezone)Path)Anydisplay_hermes_home)Platformload_gateway_config)enrich_meeting_with_call_recordfetch_preferred_transcript_textlist_recording_artifactsresolve_meeting_reference)GraphSubscription)TeamsMeetingPipeline)TeamsPipelineStore!resolve_teams_pipeline_store_path)build_graph_clientmaintain_graph_subscriptions)MicrosoftGraphConfigErrorMicrosoftGraphTokenProviderc                   | j                  d      }|j                  ddgd      }|j                  dt        d	       |j                  d
d       |j                  dd       |j                  dd      }|j                  d       |j                  dd       |j                  ddgd      }|j                  d       |j                  dd       |j                  ddgd      }|j                  dd       |j                  dd       |j                  dd       |j                  dd       |j                  ddgd      }|j                  dd       |j                  dd       }|j                  d!d"#       |j                  d$d"#       |j                  d%d       |j                  d&d       |j                  d'd       |j                  d(d       |j                  d)d*       |j                  dd       |j                  d+d,      }|j                  d-       |j                  d&d"#       |j                  dd       |j                  d.d/      }	|	j                  d-       |	j                  dd       |j                  d0d1      }
|
j                  d2t        d3	       |
j                  d4t        d3	       |
j                  d5d67       |
j                  dd       |
j                  d'd       |j                  d8d9gd:      }|j                  d;d67       |j                  d<d=      }|j                  dd       | j	                  t
        >       y )?Nteams_pipeline_action)destlistlszList recent Teams pipeline jobs)aliaseshelpz--limit   )typedefaultz--status )r"   z--store-pathshowz Show a stored Teams pipeline job)r   job_idrunreplayz"Replay a stored Teams pipeline jobfetchtestz#Dry-run meeting artifact resolutionz--meeting-idz--join-web-urlz--tenant-idz--call-record-idsubscriptionssubszList Graph subscriptions	subscribez%Create a Microsoft Graph subscriptionz
--resourceT)requiredz--notification-urlz--change-typez--expirationz--client-statez--lifecycle-notification-urlz--latest-supported-tls-versionv1_2renew-subscriptionz$Renew a Microsoft Graph subscriptionsubscription_iddelete-subscriptionz%Delete a Microsoft Graph subscriptionmaintain-subscriptionsz'Renew near-expiry managed subscriptionsz--renew-within-hours   z--extend-hoursz	--dry-run
store_true)actiontoken-healthtokenzInspect Graph token healthz--force-refreshvalidatez.Validate Teams pipeline configuration snapshot)func)add_subparsers
add_parseradd_argumentintset_defaultsteams_pipeline_command)	subparserr+   list_pshow_prun_pfetch_psubs_psub_prenew_pdelete_p
maintain_ptoken_p
validate_ps                M/root/.hermes/venv/lib/python3.12/site-packages/plugins/teams_pipeline/cli.pyregister_clirM      sn   ##)@#AD__VdV:[_\F
	R8

B/
3__V*L_MF
!
3OOEH:<`OaE	x 	~r2oogx>codG4)263+R8___vhE__`F
3OOK.UOVE	|d3	+d;	3	~r2	'4	5rB	7H	~r2oo29_o`G*+$744;bcH+,."5!9@ijJ2bI,3CK=NB7,b9oonwiFbocG*<@2bcJNB7 67    c                   t        | dd       }|st        d       y	 |dv rt        |        y|dk(  rt        |        y|dv rt	        |        y|dv rt        |        y|dv rt        |        y|d	k(  rt        |        y|d
k(  rt        |        y|dk(  rt        |        y|dk(  rt        |        y|dv rt        |        y|dk(  rt        |        yt        d|        y# t        $ r t        t                      Y yw xY w)Nr   zUsage: hermes teams-pipeline {list|show|run|fetch|subscriptions|subscribe|renew-subscription|delete-subscription|maintain-subscriptions|token-health|validate}   >   r   r   r$   >   r&   r'   >   r)   r(   >   r+   r*   r,   r/   r1   r2   >   r7   r6   r8   zUnknown teams-pipeline action: r      )getattrprint	_cmd_list	_cmd_show_cmd_run
_cmd_fetch_cmd_subscriptions_cmd_subscribe_cmd_renew_subscription_cmd_delete_subscription_cmd_maintain_subscriptions_cmd_token_health_cmd_validater   _graph_setup_hint)argsr5   s     rL   r?   r?   [   s^   T2D9FP	
 ^#dO0 / vdO, + ((TN( ' ((t$ # 00t$   {"4   ++#D)  ,,$T*  //'-  00d#  z!$  3F8<=$ !"sQ   C" C" C" C" C" .C" ?C" C" !C" 2C" C" C" "D Dc                ,    t        j                  |       S N)asyncior&   )coros    rL   
_run_asyncre      s    ;;trN   c                    t        |       S rb   )r   )path_args    rL   _store_pathrh      s    ,X66rN   c                     dt                dS )Nz3
  Microsoft Graph is not configured. Add these to z/.env:

    MSGRAPH_TENANT_ID=...
    MSGRAPH_CLIENT_ID=...
    MSGRAPH_CLIENT_SECRET=...

  Then restart the gateway or rerun this command.
r	    rN   rL   r_   r_      s     33F3H2I J rN   c                    t        j                  t        j                        t	        |       z   j                  d      j                         j                  dd      S )N)hoursr   )microsecondz+00:00Z)r   nowr   utcr   replace	isoformat)hours_from_nows    rL   _iso_utc_timestamprt      sG    LL&)HHQQ R ik''(C()rN   c                    t        | xs d      j                         j                         }|j                  d      ry|j                  d      ry|j                  d      ryy)Nr#   z/communications/onlinemeetings/getalltranscriptscreatedz.communications/onlinemeetings/getallrecordingszcommunications/callrecordsupdated)strstriplower
startswith)resource
normalizeds     rL   !_default_change_type_for_resourcer~      s[    X^$**,224JNOMN9:rN   c                    t        |       }t        |j                  d      xs i       }|j                  dd       }|rt        |      d d |d<   |xs d |d<   |S )Nsummary_payloadtranscript_text   transcript_preview)dictgetpoprx   )jobpayloadsummary
transcripts       rL   _compact_jobr      sb    3iG7;;017R8G.5J(+J(=$%!(DGNrN   activeFstatusrenewedc                   t        j                  |      j                         }||d<   |rt        d      |d<   | j	                  |d   |      S )Nr   r   latest_renewal_atr0   )r   	from_dictto_dictrt   upsert_subscription)storesubscription_payloadr   r   r}   s        rL   _sync_subscription_recordr      sT     #,,-ABJJLJ!Jx*<Q*?
&'$$Z0A%BJOOrN   c           
        t         j                  }g }g }t               }|j                  j	                  t
        j                        }|j                  j	                  t        d            }t        |j	                  d            t        |j	                  d            t        |j	                  d            d}t        |xr |j                        }t        |xr |j                        }	t        |r|j                  xs i ni       }
t        |
j	                  d      xs d      j                         xs d }t        |j                               s|j                  d       |s|j                  d	       |	s|j                  d
       n|dk(  r$|
j	                  d      s|j                  d       n|dk(  rg }t        |r|j                   ndxs |
j	                  d            }t        |j                               }|s|s|j                  d       |
j	                  d      s|j                  d       |
j	                  d      xs |
j	                  d      }|s|r|j"                  s|j                  d       |D ]  }|j                  | d        n|j                  d       | |||||	|t        | j$                        | j'                         d	S )NteamsMSGRAPH_TENANT_IDMSGRAPH_CLIENT_IDMSGRAPH_CLIENT_SECRET)	tenant_id	client_idclient_secretdelivery_moder#   z4Microsoft Graph app-only credentials are incomplete.z'MSGRAPH_WEBHOOK_ENABLED is not enabled.z$Teams outbound delivery is disabled.incoming_webhookincoming_webhook_urlzATEAMS_INCOMING_WEBHOOK_URL is required for incoming_webhook mode.graphaccess_tokenz>TEAMS_GRAPH_ACCESS_TOKEN or complete MSGRAPH_* app credentialsteam_idTEAMS_TEAM_ID
channel_idchat_idTEAMS_CHANNEL_IDz% is required for graph delivery mode.zTEAMS_DELIVERY_MODE is not set.)	okissueswarningsgraph_configwebhook_enabledteams_enabledteams_delivery_mode
store_pathstore_stats)osenvironr   	platformsr   r   MSGRAPH_WEBHOOKboolenabledr   extrarx   ry   allvaluesappendr7   home_channelpathstats)r   envr   r   gateway_configwebhook_configteams_configr   r   r   teams_extra
teams_modemissinghas_graph_delivery_tokenhas_graph_app_credentialsr   keys                    rL    _validate_configuration_snapshotr      sr   
**CFH(*N#--11(2J2JKN!++//0ABL #''"567#''"567cgg&=>?E
 >Dn.D.DEO>,*>*>?M\**0brJK[___5;<BBDLJu||~LM?@>?	)	)56MM]^	w	#'#/\R[KOON<[$
  %($7!'0INNP y)NN?+ __\2Pkooi6P
<L4M4MNN-. 	ICMMSE!FGH	I 	9: j*&)%**o{{}
 
rN   c                |   t        t        t        | dd                   }t        |j	                         j                               }t        t        | dd      xs d      j                         j                         }|r?|D cg c]4  }t        |j                  d      xs d      j                         |k(  s3|6 }}|j                  d d       t        dt        t        t        | dd	      xs d	      d
            }|d | }|st        d       y t        dt        |       d       |D ]  }|j                  d      xs i j                  d      xs d}t        d|j                  d              t        d|j                  d              t        d|        |j                  d      rt        d|j                  d              |j                  d      rt        d|j                  d              |j                  d      rt        d|j                  d              t                
 y c c}w )Nr   r   r#   c                F    t        | xs i j                  d      xs d      S )N
updated_atr#   )rx   r   )items    rL   <lambda>z_cmd_list.<locals>.<lambda>  s    sDJB#3#3L#A#GRH rN   T)r   reverserQ   limitr    d   z%No Teams meeting pipeline jobs found.
z Teams pipeline job(s):
meeting_ref
meeting_idunknown     ◆ r%   z    status: z    meeting: selected_artifact_strategyz    strategy: r   z    updated: 
error_infoz    error: )r   rh   rR   r   	list_jobsr   rx   ry   rz   r   sortmaxminr=   rS   len)r`   r   jobsr   r   r   r   s          rL   rT   rT      s   {74t+LMNE!((*+Dx,2399;AACF#Vs3778+<+B'C'I'I'Kv'UVVIIHRVIW3s74"5;<cBCE<D56	Bs4yk2
34 ww}-388FS)
swwx()*+SWWX./01j\*+77/0N377+G#H"IJK77< M#'',"7!89:77< K 5678 Ws   4H98H9c           	     F   t        t        | dd      xs d      j                         }|st        d       y t	        t        t        | dd                   }|j                  |      }|st        d|        y t        t        j                  t        |      dd             y )	Nr%   r#   job_id is requiredr   zUnknown job: rP   Tindent	sort_keys)
rx   rR   ry   rS   r   rh   get_jobjsondumpsr   )r`   r%   r   r   s       rL   rU   rU     s    x,2399;F"#{74t+LMNE
--
CfX&'	$**\#&qD
ABrN   c           	     ~   t        t        | dd      xs d      j                         }|st        d       y t	        t        t        | dd                   }t        t               |i       }t        |j                  |            }t        t        j                  t        |j                               dd             y )	Nr%   r#   r   r   )graph_clientr   configrP   Tr   )rx   rR   ry   rS   r   rh   r   r   re   run_jobr   r   r   r   )r`   r%   r   pipelineresults        rL   rV   rV   '  s    x,2399;F"#{74t+LMNE#1C1EU[]^H((01F	$**\&.."23A
NOrN   c                   t        t        | dd      xs d      j                         xs d }t        t        | dd      xs d      j                         xs d }t        t        | dd      xs d      j                         xs d }t        t        | dd      xs d      j                         xs d }|s|st        d       y t	               }t        t        ||||            }t        t        ||            \  }}t        t        ||            }	t        t        |||            }
t        t        j                  |j                         t        |xr |      |r|j                         nd |xs dd d	 xs d t        |	      |	d d
 D cg c]  }|j                          c}|
r|
j                         nd ddd             y c c}w )Nr   r#   join_web_urlr   call_record_idz&meeting_id or join_web_url is required)r   r   r   )r   r      )r   transcript_availabletranscript_artifactr   recording_count
recordingscall_recordrP   Tr   )rx   rR   ry   rS   r   re   r   r   r   r   r   r   r   r   r   )r`   r   r   r   r   clientr   r   r   r   r   	recordings               rL   rW   rW   2  s   WT<4:;AACKtJwt^R8>B?EEGO4LGD+r28b9??AITI'7<BCIIKStNl67!F!!%		
K ,66UV\^i6j+k(4V[IJJ'N[K 


*224(,-@-T_(UH[':'B'B'Dae'6'<"ds&C&Kt#&z?DNrPQNSyy002S8C{224 	
 Ts   Gc           	        t        t        t        | dd                   }t               }t	        |j                  d            }|D ]  }	 t        ||d        |st        d       y t        dt        |       d       |D ]  }t        d|j                  d	      xs d
        t        d|j                  d      xs d
        t        d|j                  d      xs d
        |j                  d      rt        d|j                  d              |j                  d      rt        d|j                  d              t                 y # t        $ r Y w xY w)Nr   /subscriptionsr   r   z'No Microsoft Graph subscriptions found.r   z" Microsoft Graph subscription(s):
r   idr   z    resource: r|   z    changeType: 
changeTypeexpirationDateTimez    expires: notificationUrlz    notify: )r   rh   rR   r   re   collect_paginatedr   	ExceptionrS   r   r   )r`   r   r   r*   subs        rL   rX   rX   Z  sQ   {74t+LMNE!Fv778HIJM 	%eSB
 78	Bs=!""E
FG swwt}1	234swwz2?i@AB !6!C) DEF77'(M#''*>"?!@AB77$%L):!; <=>  		s   
E	EEc           	        t        t        t        | dd                   }t        t        | dd      xs d      j	                         }t        t        | dd      xs d      j	                         }t        t        | dd      xs d      j	                         xs t        |      }t        t        | dd      xs d      j	                         xs t        d      }t        t        | dd      xs d      j	                         }t        t        | d	d      xs d      j	                         }t        t        | d
d      xs d      j	                         xs d}|||||d}	|r||	d<   |r||	d<   t        t               j                  d|	            }
t        ||
d       t        t        j                  |
dd             y )Nr   r|   r#   notification_urlchange_type
expirationrQ   client_statelifecycle_notification_urllatest_supported_tls_versionr.   )r   r   r|   r   latestSupportedTlsVersionclientStatelifecycleNotificationUrlr   	json_bodyr   r   rP   Tr   )r   rh   rR   rx   ry   r~   rt   re   r   	post_jsonr   rS   r   r   )r`   r   r|   r  r  r  r  lifecycle_urltls_versionr   r   s              rL   rY   rY   s  s   {74t+LMNE74R06B7==?H74);R@FBGMMOgdM26<"=CCEtIjksItKWT<4:;AAC\GYZ[G\Jwt^R8>B?EEGL&BBGM2NTTVMgd$BBGM2NTTV`Z`K "+(%0G !-.;*+*,667GSZ6[\FeVH=	$**VA
67rN   c           	        t        t        | dd      xs d      j                         }t        t        | dd      xs d      j                         }|r|st        d       y t	        t        t        | dd                   }t        t               j                  d| d|i            }d	|i|xs i d|i}t        ||d
d       t        t        j                  |dd             y )Nr0   r#   r  z-subscription_id and --expiration are requiredr   /subscriptions/r   r  r   r   Tr   rP   r   )rx   rR   ry   rS   r   rh   re   r   
patch_jsonr   r   r   )r`   r0   r  r   r   mergeds         rL   rZ   rZ     s    '$(92>D"EKKMOWT<4:;AACJ*=>{74t+LMNE''o./+Z8 	( 	
F OX"X7KZXFeVHdK	$**VA
67rN   c           	     b   t        t        | dd      xs d      j                         }|st        d       y t	        t        t        | dd                   }t        t               j                  d|             }|j                  |       t        t        j                  ||ddd	             y )
Nr0   r#   zsubscription_id is requiredr   r  )r0   r   rP   Tr   )rx   rR   ry   rS   r   rh   re   r   deletedelete_subscriptionr   r   )r`   r0   r   r   s       rL   r[   r[     s    '$(92>D"EKKMO+,{74t+LMNE*,33ooEV4WXYF	o.	$**FKTUae
fgrN   c                   t        t        t        | dd                   }t        t	        t               |t        t        | dd      xs d      t        t        | dd      xs d      t        t        | dd            t        t        | dd      xs d      j                         xs d 	            }t        t        j                  |d
d             y )Nr   renew_within_hoursr3   extend_hoursdry_runFr  r#   )r   r   r  r  r  r  rP   Tr   )r   rh   rR   re   r   r   r=   r   rx   ry   rS   r   r   )r`   r   r   s      rL   r\   r\     s    {74t+LMNE$%'"741Er#J#PbQWT>2>D"Ey%89WT>2>D"EKKMUQU	
	F 
$**VA
67rN   c                v   t        j                         }|j                         }t        |      }t	        | dd      r3	 t        |j                  d            }d|d<   t        |xs d      |d<   t        t        j                  |d	d
             y # t        $ r}d|d<   t        |      |d<   Y d }~Cd }~ww xY w)Nforce_refreshFT)r  last_refresh_succeededr#   access_token_lengthrefresh_errorrP   r   )r   from_envinspect_token_healthr   rR   re   get_access_tokenr   r  rx   rS   r   r   )r`   providerhealthr   r7   excs         rL   r]   r]     s    *335H**,F6lGt_e,	0x88t8LME04G,--0"-=G)* 
$**WQ$
78  	005G,-'*3xGO$	0s   2B 	B8B33B8c           	         t        t        t        | dd                   }t        |      }t	        t        j                  |dd             y )Nr   rP   Tr   )r   rh   rR   r   rS   r   r   )r`   r   snapshots      rL   r^   r^     s9    {74t+LMNE/6H	$**Xa4
89rN   )r@   zargparse.ArgumentParserreturnNone)r`   zargparse.Namespacer*  r=   )rg   z
str | Noner*  r   )r*  rx   )rs   r=   r*  rx   )r|   rx   r*  rx   )r   r   r*  r   )
r   r   r   dict[str, Any]r   rx   r   r   r*  r,  )r   r   r*  r,  )r*  r+  ):__doc__
__future__r   argparserc   r   r   r   r   r   pathlibr   typingr   hermes_constantsr
   gateway.configr   r   plugins.teams_pipeline.meetingsr   r   r   r   plugins.teams_pipeline.modelsr   plugins.teams_pipeline.pipeliner   plugins.teams_pipeline.storer   r   $plugins.teams_pipeline.subscriptionsr   r   tools.microsoft_graph_authr   r   rM   r?   re   rh   r_   rt   r~   r   r   r   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   rj   rN   rL   <module>r:     s    9 "    	 2 2   0 8  < @ ^ ^98x&R7	) PP(P 	P
 P P9x:
CP%P2868&h89:rN   