2424import io
2525import json
2626import logging
27+ import textwrap
2728from concurrent .futures import ThreadPoolExecutor , wait
2829from time import gmtime , sleep , strftime , time
2930
3031import psutil
3132from fake_headers import Headers , browsers
3233from requests .exceptions import RequestException
34+ from tabulate import tabulate
3335from undetected_chromedriver .patcher import Patcher
3436
3537from youtubeviewer import website
4345log = logging .getLogger ('werkzeug' )
4446log .disabled = True
4547
48+ SCRIPT_VERSION = '1.7.3'
4649
4750print (bcolors .OKGREEN + """
4851
6164 [ GitHub : https://github.com/MShawon/YouTube-Viewer ]
6265""" + bcolors .ENDC )
6366
64- SCRIPT_VERSION = '1.7.2'
67+ print (bcolors .WARNING + f"""
68+ +{ '-' * 26 } Version: { SCRIPT_VERSION } { '-' * 26 } +
69+ """ + bcolors .ENDC )
6570
6671proxy = None
67- driver = None
6872status = None
6973start_time = None
7074server_running = False
8185driver_dict = {}
8286duration_dict = {}
8387checked = {}
88+ video_statistics = {}
8489view = []
8590bad_proxies = []
8691used_proxies = []
87- console = []
8892temp_folders = []
89- threads = 0
93+ console = []
9094
91- global views
95+ threads = 0
9296views = 100
9397
9498cwd = os .getcwd ()
107111REFERERS = ['https://search.yahoo.com/' , 'https://duckduckgo.com/' , 'https://www.google.com/' ,
108112 'https://www.bing.com/' , 'https://t.co/' , '' ]
109113
114+ headers = ['Index' , 'Video Title' , 'Views' ]
115+
110116website .console = console
111117website .database = DATABASE
112118
@@ -128,10 +134,8 @@ def monkey_patch_exe(self):
128134
129135
130136def timestamp ():
131- global date_fmt , cpu_usage
137+ global date_fmt
132138 date_fmt = datetime .now ().strftime ("%d-%b-%Y %H:%M:%S" )
133- cpu = str (psutil .cpu_percent ())
134- cpu_usage = cpu + '%' + ' ' * (5 - len (cpu )) if cpu != '0.0' else cpu_usage
135139 return bcolors .OKGREEN + f'[{ date_fmt } ] | ' + bcolors .OKCYAN + f'{ cpu_usage } | '
136140
137141
@@ -299,7 +303,7 @@ def youtube_normal(method, keyword, video_title, driver, output):
299303 raise Exception (
300304 f"Can't find this [{ video_title } ] video with this keyword [{ keyword } ]" )
301305
302- skip_initial_ad (driver , output , duration_dict )
306+ skip_initial_ad (driver , video_title , duration_dict )
303307
304308 try :
305309 WebDriverWait (driver , 10 ).until (EC .visibility_of_element_located (
@@ -366,6 +370,7 @@ def control_player(driver, output, position, proxy, youtube, collect_id=True):
366370 while video_len == 0 :
367371 video_len = driver .execute_script (
368372 "return document.getElementById('movie_player').getDuration()" )
373+ sleep (1 )
369374
370375 duration_dict [output ] = video_len
371376
@@ -379,10 +384,13 @@ def control_player(driver, output, position, proxy, youtube, collect_id=True):
379384 "#23d18b" : f"{ proxy .split ('@' )[- 1 ]} --> { youtube } Found : { output } | Watch Duration : { duration } " })
380385
381386 if youtube == 'Video' and collect_id :
382- video_id = driver .find_element (
383- By .XPATH , '//*[@id="page-manager"]/ytd-watch-flexy' ).get_attribute ('video-id' )
384- if video_id and video_id not in suggested :
385- suggested .append (video_id )
387+ try :
388+ video_id = driver .find_element (
389+ By .XPATH , '//*[@id="page-manager"]/ytd-watch-flexy' ).get_attribute ('video-id' )
390+ if video_id and video_id not in suggested :
391+ suggested .append (video_id )
392+ except WebDriverException :
393+ pass
386394
387395 error = 0
388396 loop = int (video_len / 4 )
@@ -407,12 +415,16 @@ def control_player(driver, output, position, proxy, youtube, collect_id=True):
407415 if error == 10 :
408416 error_msg = f'Taking too long to play the video | Reason : buffering'
409417 if current_state == - 1 :
410- error_msg = f' Failed to play the video | Possible Reason : { proxy } not working anymore'
418+ error_msg = f" Failed to play the video | Possible Reason : { proxy . split ( '@' )[ - 1 ] } not working anymore"
411419 raise Exception (error_msg )
412420
413421 elif current_time > video_len or driver .current_url != current_url :
414422 break
415423
424+ output = textwrap .fill (text = output , width = 75 , break_on_hyphens = False )
425+ video_statistics [output ] = video_statistics .get (output , 0 ) + 1
426+ website .html_table = tabulate (video_statistics .items (), headers = headers ,
427+ showindex = True , numalign = 'center' , stralign = 'center' , tablefmt = "html" )
416428 return current_url
417429
418430
@@ -449,7 +461,7 @@ def music_and_video(proxy, position, youtube, driver, output, view_stat):
449461 for i in range (rand_choice ):
450462 if i == 0 :
451463 current_url = control_player (
452- driver , output , position , proxy , youtube )
464+ driver , output , position , proxy , youtube , collect_id = True )
453465
454466 update_view_count (position )
455467
@@ -463,7 +475,8 @@ def music_and_video(proxy, position, youtube, driver, output, view_stat):
463475 try :
464476 output = play_next_video (driver , suggested )
465477 except WebDriverException as e :
466- raise Exception (f'Error suggested | { e .args [0 ]} ' )
478+ raise Exception (
479+ f'Error suggested | { type (e ).__name__ } | { e .args [0 ]} ' )
467480
468481 print (timestamp () + bcolors .OKBLUE +
469482 f"Worker { position } | Found next suggested video : [{ output } ]" + bcolors .ENDC )
@@ -476,7 +489,7 @@ def music_and_video(proxy, position, youtube, driver, output, view_stat):
476489 features (driver )
477490
478491 current_url = control_player (
479- driver , output , position , proxy , youtube )
492+ driver , output , position , proxy , youtube , collect_id = False )
480493
481494 update_view_count (position )
482495
@@ -495,7 +508,8 @@ def channel_or_endscreen(proxy, position, youtube, driver, view_stat, current_ur
495508 try :
496509 output , log , option = play_from_channel (driver , channel_name )
497510 except WebDriverException as e :
498- raise Exception (f'Error channel | { e .args [0 ]} ' )
511+ raise Exception (
512+ f'Error channel | { type (e ).__name__ } | { e .args [0 ]} ' )
499513
500514 print (timestamp () + bcolors .OKBLUE +
501515 f"Worker { position } | { log } " + bcolors .ENDC )
@@ -506,7 +520,8 @@ def channel_or_endscreen(proxy, position, youtube, driver, view_stat, current_ur
506520 try :
507521 output = play_end_screen_video (driver )
508522 except WebDriverException as e :
509- raise Exception (f'Error end screen | { e .args [0 ]} ' )
523+ raise Exception (
524+ f'Error end screen | { type (e ).__name__ } | { e .args [0 ]} ' )
510525
511526 print (timestamp () + bcolors .OKBLUE +
512527 f"Worker { position } | Video played from end screen : [{ output } ]" + bcolors .ENDC )
@@ -538,7 +553,7 @@ def windows_kill_drivers():
538553
539554
540555def quit_driver (driver , data_dir ):
541- if driver in driver_dict :
556+ if driver and driver in driver_dict :
542557 driver .quit ()
543558 if data_dir in temp_folders :
544559 temp_folders .remove (data_dir )
@@ -553,6 +568,8 @@ def quit_driver(driver, data_dir):
553568
554569def main_viewer (proxy_type , proxy , position ):
555570 global width , viewports
571+ driver = None
572+ data_dir = None
556573
557574 if cancel_all :
558575 raise KeyboardInterrupt
@@ -595,6 +612,7 @@ def main_viewer(proxy_type, proxy, position):
595612
596613 while proxy in bad_proxies :
597614 bad_proxies .remove (proxy )
615+ sleep (1 )
598616
599617 patched_driver = os .path .join (
600618 patched_drivers , f'chromedriver_{ position % threads } { exe_name } ' )
@@ -668,12 +686,11 @@ def main_viewer(proxy_type, proxy, position):
668686 status = quit_driver (driver = driver , data_dir = data_dir )
669687
670688 except Exception as e :
671- * _ , exc_tb = sys .exc_info ()
672689 print (timestamp () + bcolors .FAIL +
673- f"Worker { position } | Line : { exc_tb . tb_lineno } | " + str ( e .args [0 ]) + bcolors .ENDC )
690+ f"Worker { position } | Line : { e . __traceback__ . tb_lineno } | { type ( e ). __name__ } | { e .args [0 ]} " + bcolors .ENDC )
674691
675692 create_html (
676- {"#f14c4c" : f"Worker { position } | Line : { exc_tb . tb_lineno } | " + str ( e .args [0 ]) })
693+ {"#f14c4c" : f"Worker { position } | Line : { e . __traceback__ . tb_lineno } | { type ( e ). __name__ } | { e .args [0 ]} " })
677694
678695 status = quit_driver (driver = driver , data_dir = data_dir )
679696
@@ -689,10 +706,10 @@ def main_viewer(proxy_type, proxy, position):
689706
690707 except Exception as e :
691708 print (timestamp () + bcolors .FAIL +
692- f"Worker { position } | { e .args [0 ]} " + bcolors .ENDC )
709+ f"Worker { position } | Line : { e . __traceback__ . tb_lineno } | { type ( e ). __name__ } | { e .args [0 ]} " + bcolors .ENDC )
693710
694711 create_html (
695- {"#f14c4c" : f"Worker { position } | { e .args [0 ]} " })
712+ {"#f14c4c" : f"Worker { position } | Line : { e . __traceback__ . tb_lineno } | { type ( e ). __name__ } | { e .args [0 ]} " })
696713
697714
698715def get_proxy_list ():
@@ -794,7 +811,7 @@ def view_video(position):
794811
795812
796813def main ():
797- global cancel_all , proxy_list , total_proxies , threads , hash_config , futures
814+ global cancel_all , proxy_list , total_proxies , threads , hash_config , futures , cpu_usage
798815
799816 cancel_all = False
800817 start_time = time ()
@@ -819,7 +836,8 @@ def main():
819836 if api :
820837 threads += 1
821838
822- pool_number = [i for i in range (total_proxies )]
839+ loop = 0
840+ pool_number = list (range (total_proxies ))
823841
824842 with ThreadPoolExecutor (max_workers = threads ) as executor :
825843 futures = [executor .submit (view_video , position )
@@ -830,7 +848,16 @@ def main():
830848 while not_done :
831849 freshly_done , not_done = wait (not_done , timeout = 1 )
832850 done |= freshly_done
833- sleep (15 )
851+
852+ loop += 1
853+ for _ in range (70 ):
854+ cpu = str (psutil .cpu_percent (0.2 ))
855+ cpu_usage = cpu + '%' + ' ' * \
856+ (5 - len (cpu )) if cpu != '0.0' else cpu_usage
857+
858+ if loop % 40 == 0 :
859+ print (tabulate (video_statistics .items (),
860+ headers = headers , showindex = True , tablefmt = "pretty" ))
834861
835862 if len (view ) >= views :
836863 print (timestamp () + bcolors .WARNING +
@@ -886,7 +913,7 @@ def main():
886913
887914 clean_exe_temp (folder = 'youtube_viewer' )
888915 date_fmt = datetime .now ().strftime ("%d-%b-%Y %H:%M:%S" )
889- cpu_usage = str (psutil .cpu_percent ())
916+ cpu_usage = str (psutil .cpu_percent (1 ))
890917 update_chrome_version ()
891918 check_update ()
892919 osname , exe_name = download_driver (patched_drivers = patched_drivers )
0 commit comments