U
    g                     @   s   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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 G dd dZdS )    N)BeautifulSoup)urlparseparse_qsc                   @   s|   e Z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%ddZd&ddZd'ddZd(dd ZdS ))VideoDownloader	downloads/var/www/html/downloadshttp://8.215.44.123/downloadsc                 C   sP   || _ || _|| _tj|dd tjdtjd tt	| _
ddddd	g| _d S )
NTexist_okz4%(asctime)s - %(name)s - %(levelname)s - %(message)s)formatlevelzsMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36zuMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15ziMozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36zNMozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1)download_pathpublic_path
public_urlosmakedirsloggingbasicConfigINFO	getLogger__name__loggeruser_agents)selfr   r   r    r   </var/www/html/botvid/final_all_platforms_fixed_downloader.py__init__   s    zVideoDownloader.__init__c                 C   sP   d|ksd|krdS d|ks,d|ks,d|kr0dS d|kr<d	S d
|krHdS dS dS )z#Determine the platform from the URLzyoutube.comyoutu.beyoutubezfacebook.comzfb.comzfb.watchZfacebookzinstagram.com	instagramz
tiktok.comZtiktokZgenericNr   )r   urlr   r   r   get_platform(   s    zVideoDownloader.get_platformc                 C   s   t | jS )z%Get a random user agent from the list)randomchoicer   )r   r   r   r   get_random_user_agent5   s    z%VideoDownloader.get_random_user_agentc                 C   sN   d|kr&t |j}|ddd S t |}t|j}|ddgd S dS )z!Extract YouTube video ID from URLr   /?r   v N)r   pathstripsplitr   queryget)r   r!   r*   Z
parsed_urlZquery_paramsr   r   r   get_youtube_video_id9   s    

z$VideoDownloader.get_youtube_video_idc                 C   s   t d|}|r|dS dS )z$Extract Instagram shortcode from URLz"instagram\.com/(?:p|reel)/([^/?]+)   N)researchgroup)r   r!   matchr   r   r   get_instagram_shortcodeE   s    
z'VideoDownloader.get_instagram_shortcode
   Nc                 C   sf  z| j d| d| d |dkrDtj|\}}| d| }ztjddgtjtjdd	 W n, tjt	fk
r   | j 
d
 | Y W S X ddddddd|g}tj|tjtjdd}|jdkr| j 
d|j  |W S t|j }|d d d }	t|	|d  }
dd|dt|
dt|
dt|
d dddd d!|g}| j d"d#|  tj|tjtjd$}|jdkr| j 
d%|j  |W S tj|r
tj|d& }tj|d& }| j d'|d(d)|d(d ||k r|W S | j d* t| |W S n| j 
d+ |W S W nB tk
r` } z"| j 
d,t|  | W Y S d}~X Y nX dS )-z#Compress video to target size in MBzCompressing video: z to target size: MBNZ_compressedffmpegz-versionT)stdoutstderrcheckz(ffmpeg not found. Please install ffmpeg.Zffprobez-verrorz-show_entrieszformat=durationz-ofz"default=noprint_wrappers=1:nokey=1)r9   r:   textr   zError getting video duration:    i   g333333?-iz-b:vz-maxratez-bufsize   z-c:aZaacz-b:a128k-yzRunning ffmpeg command:  r9   r:   zError compressing video:    zOriginal size: .2fzMB, Compressed size: zBCompressed file is not smaller than original. Using original file.zCompressed file was not createdzError in compress_video: )r   infor   r*   splitext
subprocessrunPIPESubprocessErrorFileNotFoundErrorr<   
returncoder:   floatr9   r+   intstrjoinexistsgetsizewarningremove	Exception)r   
input_filetarget_size_mboutput_file	file_namefile_extcmdresultdurationZtarget_size_bitsZbitrateZoriginal_sizeZcompressed_sizeer   r   r   compress_videoM   sr    
  
     
    	


zVideoDownloader.compress_video   c              
   C   s  zt j| jdd t jt j|\}}tt dd }d	dd |D }| d| | }t j	| j|}	t
||	 | j d	| }
|	 d
}t|db}|d| d |dt j| d |dtdgd  |d| d W 5 Q R X zTd|	 d| }d| d}tjd| d| dd | jd|	 d| d W n6 tk
r } z| jd|  W 5 d}~X Y nX d|
|	|dW S  tk
r } z,| jdt|  d t|d! W Y S d}~X Y nX dS )"z(Create a public download link for a fileTr	   Nr>   r)   c                 s   s&   | ]}|  s|d kr|ndV  qdS ))-_rd   N)isalnum).0cr   r   r   	<genexpr>   s     z>VideoDownloader.create_public_download_link.<locals>.<genexpr>rd   r&   z.infowzTitle: 
zOriginal file: z	Created: datezutf-8zExpires: After z hours
zrm -f rC   znow + z hourszecho "z" | at )shellzScheduled deletion of z after z"Could not schedule file deletion: )successr!   	file_pathZexpires_in_hourszError creating download link: Frm   r<   )r   r   r   r*   rH   basenamerQ   uuiduuid4rR   shutilcopy2r   openwriterI   check_outputdecoderJ   r   rG   rW   rU   r<   )r   rn   titleexpiry_hoursr[   r\   Z	unique_idZ
safe_titleZpublic_filenameZpublic_file_pathdownload_urlZinfo_file_pathfZ
delete_cmdZat_timer`   r   r   r   create_public_download_link   s@    
$z+VideoDownloader.create_public_download_linkFc              
   C   s  z|  |}|sdddW S | jd|  zt }|jd|  i d}d| dd	d
}|j||dd}|j	dkr|
 }d|krt|d d}	|	d}
|
r|
j nd| }|r|	d}n|	d}|s|	d}|r|d}|rd}d||dd|rdnd|r&dndd}|j||dd}|j	dkr|
 }d|krt|d d}	|	d}|r|d r|d  }|rdnd}tj| jd!| d"| }|j|d#d$d%}|j	dkrt|d&$}|jd'd(D ]}|| qW 5 Q R X d#|||d)W W S W n: tk
rV } z| jd*t|  W 5 d+}~X Y nX zd,}|  d-d-d.}||r|dndd/}tj|||d0d1}|j	dkrn|
 }d2|krn|d2 rn|d2 }|d3d| }|rdnd}tj| jd!| d"| }tj|d|  id#d$d4}|j	dkrnt|d&$}|jd'd(D ]}|| q@W 5 Q R X d#|||d)W W S W n: tk
r } z| jd5t|  W 5 d+}~X Y nX | ||W S  tk
r } z*| jd6t|  | || W Y S d+}~X Y nX d+S )7z0Download YouTube video using direct API approachFz"Could not extract YouTube video IDro   z.Attempting to download YouTube video with ID: 
User-Agentz)https://www.y2mate.com/mates/analyze/ajaxz https://www.youtube.com/watch?v=r   r0   )r!   Zq_autoajax   )datatimeout   r^   zhtml.parserz.caption > bzYouTube Video z(a[data-ftype="mp3"][data-fquality="128"]z)a[data-ftype="mp4"][data-fquality="720p"]z)a[data-ftype="mp4"][data-fquality="360p"]zdata-idz$https://www.y2mate.com/mates/convertr   1r)   mp3mp4Z128Z720p)type_idZv_idr   tokenZftypeZfqualityza.btn-successZhrefZyoutube_.T   )streamr   wb    
chunk_sizerm   rn   ry   r   zY2mate approach failed: N$https://api.savefrom.net/api/convertapplication/jsonr~   Content-TypeAcceptr!   	extension   headersjsonr   r!   ry   r   r   r   Savefrom approach failed: z&Error in direct YouTube API download: )r/   r   rG   requestsZSessionr   updater%   poststatus_coder   r   Z
select_oner=   r+   r.   r   r*   rR   r   ru   iter_contentrv   rW   rU   rQ   download_with_ytdlpr<   )r   r!   
audio_onlyZvideo_idsessionZanalyze_urlr   responseZanalyze_dataZsoupZ
title_elemry   Z
format_btnkZconvert_urlZconvert_dataZdownload_linkr{   extrZ   r|   chunkr`   api_urlr   api_datar   r   r    download_with_direct_youtube_api   s    








((z0VideoDownloader.download_with_direct_youtube_apic              
   C   s  z|  |}|sdddW S | jd|  zd}|  dddd	d
}d|i}tj|||dd}|jdkr| }d|kr|d rd}	|d D ] }
|
ddkr|
d}	 qq|	r|dd| }|rdnd}t	j
| jd| d| }tj|	d|  iddd}|jdkrt|d$}|jddD ]}|| q:W 5 Q R X |rt	j
| jd| d }d!d"|d#d$d%d&d'd(|g
}tj|tjtjd) t	| |}d}d|||d*W W S W n: tk
r  } z| jd+t|  W 5 d}~X Y nX zrd,}|  ddd-}||r&dndd.}tj|||dd/}|jdkrt| }d|krt|d rt|d }|dd| }|rdnd}t	j
| jd| d| }tj|d|  iddd}|jdkrtt|d$}|jddD ]}|| qW 5 Q R X |rbt	j
| jd| d }d!d"|d#d$d%d&d'd(|g
}tj|tjtjd) t	| |}d}d|||d*W W S W n: tk
r } z| jd0t|  W 5 d}~X Y nX | ||W S  tk
r } z*| jd1t|  | || W Y S d}~X Y nX dS )2z2Download Instagram video using direct API approachFz%Could not extract Instagram shortcodero   z6Attempting to download Instagram post with shortcode: z,https://sssinstagram.com/api/instagram/mediaz!application/x-www-form-urlencodedr   zhttps://sssinstagram.comzhttps://sssinstagram.com/en)r~   r   r   OriginRefererr!   r   )r   r   r   r   ZmediasNr   videory   zInstagram Post r   r   
instagram_r   r~   Tr   r   r   r   r   z.mp3r8   r?   z-vnz-abrA   z-arZ44100rB   rD   r   zsssinstagram approach failed: r   r   r   r   r   z(Error in direct Instagram API download: )r5   r   rG   r%   r   r   r   r   r.   r   r*   rR   r   ru   r   rv   rI   rJ   rK   rV   rW   rU   rQ   download_with_ytdlp_instagramr<   r   )r   r!   r   	shortcoder   r   r   r   r   	video_urlmediary   r   rZ   r|   r   Zmp3_filer]   r`   r{   r   r   r   "download_with_direct_instagram_apiJ  s    
	 
        
(        
(z2VideoDownloader.download_with_direct_instagram_apic                    sx  z$ddl }d}tjt d}t|d}|| W 5 Q R X | |}d|rV|nt	d
   tj| j }|d d	d	d
d
d
d
dddd|dddddd|rdndd}	|r|	dddddgi d}
nd}
||	:}| jd| d |j|d
d}zt| W n   Y nX |sBd	d d!W  5 Q R  W S d"|krz|d" snd	d#d!W  5 Q R  W S |d" d }|s|d$d}
|d%d&}| d'|
 }tj|s fd(d)t| jD }|rtj| j|d }nd	d*d!W  5 Q R  W S d
|||
d+W  5 Q R  W S Q R X W nL tk
rr } z,| jd,t|  d	t|d! W Y S d}~X Y nX dS )-z2Download Instagram video using yt-dlp with cookiesr   NaI  # Netscape HTTP Cookie File
.instagram.com	TRUE	/	TRUE	1798869816	csrftoken	dummy_csrftoken
.instagram.com	TRUE	/	TRUE	1798869816	ds_user_id	dummy_user_id
.instagram.com	TRUE	/	TRUE	1798869816	ig_did	dummy_ig_did
.instagram.com	TRUE	/	TRUE	1798869816	mid	dummy_mid
.instagram.com	TRUE	/	TRUE	1798869816	sessionid	dummy_sessionid
zinstagram_cookies.txtri   r      .%(ext)sFTUSr   <   r   en-US,en;q=0.9Jtext/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8zhttps://www.instagram.com/zhttps://www.instagram.com)r~   Accept-Languager   r   r   bestaudio/bestbest)outtmplquietno_warningsverboseignoreerrorsnocheckcertificate
geo_bypassgeo_bypass_countryretriesfragment_retriessocket_timeoutZ
cookiefilehttp_headersr   postprocessorsFFmpegExtractAudior   192keyZpreferredcodecZpreferredqualityr   Attempting to download z with yt-dlp and cookiesdownloadz/Failed to extract video information with yt-dlpro   entries#Empty playlist or all videos failedr   ry   zInstagram Videor   c                    s   g | ]}|  r|qS r   
startswithrf   r|   filenamer   r   
<listcomp>!  s     
 zAVideoDownloader.download_with_ytdlp_instagram.<locals>.<listcomp>Downloaded file not foundr   z$Error in Instagram yt-dlp download: )yt_dlpr   r*   rR   tempfile
gettempdirru   rv   r5   urandomhexr   r   	YoutubeDLr   rG   extract_inforV   r.   rS   listdirrW   r<   rQ   )r   r!   r   r   Zcookies_contentZcookies_filer|   r   output_templateydl_opts	final_extydlrG   ry   rn   possible_filesr`   r   r   r   r     s    



z-VideoDownloader.download_with_ytdlp_instagramc                    s@  zddl }| |}| dtd   tj| j }t	t
dd |d ddd	d	d	d	d
ddd|  ddddddgdd	d}|dkr|ddd	dddddgddgdiddd	dd |r|d d!d"d#d$gd% d"}n|dkr|d&d'i d}g }z ||}	| jd(| d) |	j|d	d*}
|
rd+|
krf|
d+ sZtd,|
d+ d }
|sx|
d-d}|
d.d/}| d0| }tj|sއ fd1d2t| jD }|rtj| j|d }ntd3d	|||d4W  5 Q R  W W S W 5 Q R X W nN tk
rV } z.|d5t|  | jd6t|  W 5 d}~X Y nX z| }|d'd	d7 ||}	| jd(| d8 |	j|d	d*}
|
rfd+|
kr|
d+ std,|
d+ d }
|s|
d-d}|
d.d/}| d0| }tj|sH fd9d2t| jD }|r@tj| j|d }ntd3d	|||d4W  5 Q R  W W S W 5 Q R X W nN tk
r } z.|d:t|  | jd;t|  W 5 d}~X Y nX d<|}| jd=|  dd>| d?W S  tk
r: } z,| jd@t|  dt|d? W Y S d}~X Y nX dS )Az8Download video using yt-dlp with improved error handlingr   Nrd   r   g      ?r@   r   FTr   r   r   r   r   zhttps://www.google.com/)r~   r   r   r   z--max-retries10)r   r   r   r   r   r   r   r   r   r   r   r   Zexternal_downloader_argsZhls_prefer_nativeZhls_use_mpegtsr   z8bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/bestr   ZandroidZwebZtv_embeddedZiosZdashZhls)Zplayer_clientskipr6   )r   Zmerge_output_formatZ
noplaylistZextractor_argsZextractor_retriesZyoutube_include_dash_manifestZprefer_insecureforce_generic_extractorr   r   r   r   r   )r   r   r   r   r   z with yt-dlp (attempt 1)r   r   r   r   ry   Videor   c                    s   g | ]}|  r|qS r   r   r   r   r   r   r     s     
 z7VideoDownloader.download_with_ytdlp.<locals>.<listcomp>r   r   zAttempt 1 failed: zFirst download attempt failed: )r   r   z with yt-dlp (attempt 2)c                    s   g | ]}|  r|qS r   r   r   r   r   r   r     s     
 zAttempt 2 failed: z Second download attempt failed: z; zAll download attempts failed: z=Failed to extract video information after multiple attempts: ro   zError in download_with_ytdlp: )r   r"   r   r   r   r*   rR   r   timesleepr#   uniformr%   r   r   r   rG   r   rW   r.   rS   r   appendrQ   rU   copyr<   )r   r!   r   r   platformr   r   r   Zerror_messagesr   rG   ry   rn   r   r`   Zsecond_attempt_optsZerror_summaryr   r   r   r   1  s    

 

$(

$(
z#VideoDownloader.download_with_ytdlpTc                 C   sF  | j d| d| d|  | |}| j d|  |dkrP| ||}n"|dkrf| ||}n| ||}|d rB|sB|rB|d }tj|d	 }||kr| j d
|dd| d | 	||}	|	|kr|	|d< d|d< tj|	d	 }
| j d|
dd nd|d< n$| j d
|dd| d d|d< |S )z3Main download method with multiple fallback optionszStarting download for z, audio_only=z, compress=zDetected platform: r   r    rm   rn   rE   zFile size (rF   zMB) exceeds target size (zMB). Compressing...T
compressedz Compression complete. New size: r7   Fz"MB) is already below target size (zMB). Skipping compression.)
r   rG   r"   r   r   r   r   r*   rT   ra   )r   r!   r   compressrY   r   r^   rn   Zfile_size_mbZcompressed_pathZnew_size_mbr   r   r   r     s.    



zVideoDownloader.download)r   r   r   )r6   N)rb   )F)F)F)F)FTr6   )r   
__module____qualname__r   r"   r%   r/   r5   ra   r}   r   r   r   r   r   r   r   r   r   r      s   

F
3
 
 
f
 )r   )r   r   rI   r   rq   rs   r   r#   r1   r   r   Zbs4r   urllib.parser   r   r   r   r   r   r   <module>   s   