U
    ؎jR%                     @   sF  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Zd dlmZ d dl	m
Z
m	Z	mZ d dlm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 d d	lmZ ed
ddZe ZeddZdd Zdd Z dd Z!dd Z"dd Z#dd Z$dd Z%dd Z&dd  Z'd!d" Z(d#d$ Z)d%d& Z*d'd( Z+d)d* Z,d+d, Z-dS )-    N)ThreadPoolExecutor)datedatetime	timedelta)Path)settings)File)close_old_connections)Q)Live_Lecture   zzoom-recording)max_workersthread_name_prefixrez^[a-f0-9]{32}$c                  C   s&   t tdd} t| p"tjt dS )NZZOOM_RECORDING_SPOOL_ROOT zcet-zoom-recording-jobs)getattrr   r   ospathjointempfile
gettempdir
configured r   =/var/www/html/crackeverytest/admin_app/zoom_recording_jobs.py
spool_root   s    r   c                 C   s$   t t| pdstdt |  S )Nr   zInvalid Zoom recording job id.)_JOB_ID_PATTERN	fullmatchstr
ValueErrorr   job_idr   r   r   _job_dir   s    r"   c                 C   s   t | d S )Nzstatus.json)r"   r    r   r   r   _status_path%   s    r#   c              	   C   sx   t | }|jddd t  d |d< t| d}t2 |jt	
|dd tt|tt|  W 5 Q R X d S )NTparentsexist_okZ
updated_atz.tmputf-8encoding)r"   mkdirr   utcnow	isoformatr#   with_suffix_status_lock
write_textjsondumpsr   replacer   )r!   statusjob_dir	temporaryr   r   r   _write_status)   s    r8   c              
   C   sB   t | }| sd S t  t|jddW  5 Q R  S Q R X d S Nr)   r*   )r#   existsr0   r2   loads	read_textr!   r   r   r   r   read_zoom_recording_job3   s
    r>   c                   C   s
   t  d S )Nzactive.lock)r   r   r   r   r   _active_lock_path;   s    r?   c                 C   s  t  }|jddd t }tttdd}| rnt 	 |
 j |krnz|  W n tk
rl   Y nX z"tt|tjtjB tjB }W nT tk
r   z"|jdd }dt|fW  Y S  ttfk
r   Y Y dS X Y nX t|d	}||  W 5 Q R X d
S )NTr$   ZZOOM_RECORDING_LOCK_TIMEOUTi`T  r)   r*   F)FNw)TN)r   r,   r?   intr   r   r:   r   now	timestampstatst_mtimeunlinkOSErrorr   openr   O_CREATO_EXCLO_WRONLYFileExistsErrorr<   stripr>   r   fdopenwrite)r!   rootr   Zstale_seconds
descriptorZactive_job_idZ	lock_filer   r   r   _acquire_active_lock?   s(    ""rR   c                 C   s@   t  }z |jdd | kr$|  W n tk
r:   Y nX d S r9   )r?   r<   rM   rF   rG   r=   r   r   r   _release_active_lockY   s    rS   c               
   C   s   t  j} t| \}}|s,|p&ddddfS | ddddddg t  d d	}t| | zt	t
|  W n tk
r   t|   Y nX |d	fS )
N
processingz(A Zoom recording job is already running.)statemessageFqueuedr   r'   )	r!   rU   total	processeduploadedskippedfailederrors
created_atT)uuiduuid4hexrR   r   r-   r.   r8   	_executorsubmit_process_zoom_recordings	ExceptionrS   )r!   acquiredZactive_statusr5   r   r   r   queue_zoom_recording_jobb   s4    

rg   c                 C   s6   t jdd| jd| j| jfdd}|  | d S )Nzhttps://zoom.us/oauth/tokenZaccount_credentials)
grant_type
account_id
      )paramsauthtimeoutaccess_token)requestspostri   	client_idclient_secretraise_for_statusr2   )zoom_keyresponser   r   r   _zoom_access_token   s    
	rx   c                 C   s   t jd| dd|idd}|jdkr.g S |jdkrjz| dd	krRg W S W n tk
rh   Y nX |  | d
g }dd |D }t|dd ddS )Nz.https://api.zoom.us/v2/meetings/{0}/recordingsAuthorizationz
Bearer {0}rj   )headersro   i  i  codei  recording_filesc                 S   sX   g | ]P}t |d p |dp d dkr|drt |dpDd dkr|qS )	file_typefile_extensionr   MP4download_urlr5   	completed)r   getupperlower).0itemr   r   r   
<listcomp>   s
   $
z$_zoom_recordings.<locals>.<listcomp>c                 S   s   t | dpdS )N	file_sizer   )rA   r   )r   r   r   r   <lambda>       z"_zoom_recordings.<locals>.<lambda>T)keyreverse)rq   r   formatstatus_coder2   r   ru   sorted)
meeting_idrp   rw   filesZ	mp4_filesr   r   r   _zoom_recordings   s&    


r   c                  C   s8   t tdd} | r.tj| r.t| tjr.| S tdS )NFFMPEG_BINARYr   ffmpeg)	r   r   r   r   isfileaccessX_OKshutilwhichr   r   r   r   _ffmpeg_binary   s    r   c                 C   s   t  }|stdtj|dd| dddddd	d
ddddddddd|gtjtjtttdddd}|j	dkr|j
jddddd  }td|d S )Nz;FFmpeg is not installed or FFMPEG_BINARY is not configured.z-yz-iz-map_metadataz-1z-c:vlibx264z-presetfastz-crf28z-pix_fmtyuv420pz-c:aaacz-b:a96kz	-movflagsz
+faststartZZOOM_RECORDING_FFMPEG_TIMEOUTi   F)stdoutstderrro   checkr   r)   r4   )r]   i$zFFmpeg compression failed: {0})r   RuntimeError
subprocessrunDEVNULLPIPErA   r   r   
returncoder   decoder   )sourcedestinationbinaryresultdetailsr   r   r   	_compress   sD                  	
r   c              
   C   s|   d| krdnd}d | ||}tj|dddD}|  t|d&}|jdd	D ]}|rP|| qPW 5 Q R X W 5 Q R X d S )
N?&z{0}{1}access_token={2}T)rl      )streamro   wbi   )
chunk_size)r   rq   r   ru   rH   iter_contentrO   )r   rp   r   	separatorurlrw   outputchunkr   r   r   	_download   s    r   c                 C   s(  t   t| }d|d< t| | t| }zʐzt	 }t
ttdd}t
ttdd}ttjjtd	d
tddB |tdd |gddjddjd	ddddd | }t||d< t| | |D ]}|d |kr qz|j|d< |j|d< t| | |d|j }|d|j }	zzt|j}t|j|}|s\|d  d7  < W W qt |d d |t!| t"t!|t!|	 |	#d (}|j$j%d!t&' j(t)|dd" W 5 Q R X |d  d7  < W nR t*k
r" } z2|d#  d7  < |d$ +|j|jt!|d% W 5 d }~X Y nX W 5 |d  d7  < ||	fD ]*}
z|
  W n tk
rf   Y nX q@t| | X q|d# dkrd&nd'|d< |,dd  |,dd  W nB t*k
r } z"d#|d< |d$ +d(t!|i W 5 d }~X Y nX W 5 t  d |d< t| | t|  t   X d S ))NrT   rU   r'   finished_atZZOOM_RECORDING_CANDIDATE_LIMITd   ZZOOM_RECORDING_UPLOADS_PER_JOBr   r   )videosT)videos__isnull   )daysF)lacture_date__rangezoom_key__isnull)meeting_id__isnull)r   rv   z-lacture_date
start_timerX   rZ   Zcurrent_lecture_idZcurrent_lecture_titlez{0}-input.mp4z{0}-compressed.mp4rY   r[   r   r   rbz{0}.mp4)saver\   r]   )
lecture_idlecture_titleerrorr   completed_with_errorsr   )-r	   r>   r8   r"   r   r-   r.   rS   r   todayrA   r   r   listr   objectsfilterr
   r   excludeselect_relatedorder_bylenidtitler   rF   rG   rx   rv   r   r   r   r   r   rH   r   r   r_   r`   ra   r   re   appendpop)r!   r5   r6   r   Zcandidate_limitZupload_limitlectureslecture
input_pathoutput_pathr   rp   
recordings
compressedexcr   r   r   rd      s    
 	






,
rd   ).r2   r   r   r   r   	threadingr_   concurrent.futuresr   r   r   r   pathlibr   rq   django.confr   django.core.filesr   	django.dbr	   django.db.modelsr
   Zlearn.modelsr   rb   Lockr0   
__import__compiler   r   r"   r#   r8   r>   r?   rR   rS   rg   rx   r   r   r   r   rd   r   r   r   r   <module>   sB   
	