def testDownloadVideosReferencedInPlaylistForPlaylistUrlMultipleVideo(self): playlistName = 'test_audio_downloader_two_files' downloadDir = AUDIO_DIR_TEST + DIR_SEP + playlistName if not os.path.exists(downloadDir): os.mkdir(downloadDir) # deleting files in downloadDir files = glob.glob(downloadDir + DIR_SEP + '*') for f in files: os.remove(f) guiOutput = GuiOutputStub() youtubeAccess = YoutubeDlAudioDownloader(guiOutput, AUDIO_DIR_TEST) playlistUrl = "https://www.youtube.com/playlist?list=PLzwWSJNcZTMRGA1T1vOn500RuLFo_lGJv" stdout = sys.stdout outputCapturingString = StringIO() sys.stdout = outputCapturingString _, downloadVideoInfoDic, _, accessError = youtubeAccess.getDownloadVideoInfoDicOrSingleVideoTitleFortUrl(playlistUrl) downloadVideoInfoDic, accessError = youtubeAccess.downloadVideosReferencedInPlaylistForPlaylistUrl(playlistUrl, downloadVideoInfoDic) targetAudioDir = downloadVideoInfoDic.getPlaylistDownloadDir() sys.stdout = stdout self.assertIsNone(accessError) self.assertEqual(['downloading "Wear a mask. Help slow the spread of Covid-19." audio ...', '', '"Wear a mask. Help slow the spread of Covid-19." audio downloaded.', '', 'downloading "Here to help: Give him what he wants" audio ...', '', '"Here to help: Give him what he wants" audio downloaded.', '', '"test_audio_downloader_two_files" playlist audio(s) download terminated.', '', ''], outputCapturingString.getvalue().split('\n')) self.assertEqual(downloadDir, targetAudioDir) self.assertEqual('Wear a mask. Help slow the spread of Covid-19.', downloadVideoInfoDic.getVideoTitleForVideoIndex(1)) self.assertEqual('https://www.youtube.com/watch?v=9iPvLx7gotk', downloadVideoInfoDic.getVideoUrlForVideoIndex(1)) self.assertEqual('https://www.youtube.com/watch?v=9iPvLx7gotk', downloadVideoInfoDic.getVideoUrlForVideoTitle('Wear a mask. Help slow the spread of Covid-19.')) self.assertEqual('Wear a mask. Help slow the spread of Covid-19..mp3', downloadVideoInfoDic.getVideoFileNameForVideoIndex(1)) self.assertEqual('Wear a mask. Help slow the spread of Covid-19..mp3', downloadVideoInfoDic.getVideoFileNameForVideoTitle('Wear a mask. Help slow the spread of Covid-19.')) self.assertEqual('Here to help: Give him what he wants', downloadVideoInfoDic.getVideoTitleForVideoIndex(2)) self.assertEqual('https://www.youtube.com/watch?v=Eqy6M6qLWGw', downloadVideoInfoDic.getVideoUrlForVideoIndex(2)) self.assertEqual('https://www.youtube.com/watch?v=Eqy6M6qLWGw', downloadVideoInfoDic.getVideoUrlForVideoTitle('Here to help: Give him what he wants')) self.assertEqual('Here to help - Give him what he wants.mp3', downloadVideoInfoDic.getVideoFileNameForVideoIndex(2)) self.assertEqual('Here to help - Give him what he wants.mp3', downloadVideoInfoDic.getVideoFileNameForVideoTitle('Here to help: Give him what he wants')) self.assertEqual(['1', '2'], downloadVideoInfoDic.getVideoIndexes()) fileNameLst = [x.split(DIR_SEP)[-1] for x in glob.glob(downloadDir + DIR_SEP + '*.*')] self.assertEqual(sorted(['Here to help - Give him what he wants.mp3', 'Wear a mask. Help slow the spread of Covid-19..mp3', 'test_audio_downloader_two_files_dic.txt']), sorted(fileNameLst))
def testDownloadVideosReferencedInPlaylistForPlaylistUrl_with_timeFrame(self): playlistName = 'Test_title_one_time_frame_extract' downloadDir = AUDIO_DIR_TEST + DIR_SEP + playlistName # timeInfo = '(e0:0:5-0:0:10)' if not os.path.exists(downloadDir): os.mkdir(downloadDir) # deleting files in downloadDir files = glob.glob(downloadDir + DIR_SEP + '*') for f in files: os.remove(f) guiOutput = GuiOutputStub() youtubeAccess = YoutubeDlAudioDownloader(guiOutput, AUDIO_DIR_TEST) playlistUrl = "https://www.youtube.com/playlist?list=PLzwWSJNcZTMTB7GasAttwVnPPk3-WTMNJ" stdout = sys.stdout outputCapturingString = StringIO() sys.stdout = outputCapturingString _, downloadVideoInfoDic, _, accessError = youtubeAccess.getDownloadVideoInfoDicOrSingleVideoTitleFortUrl(playlistUrl) downloadVideoInfoDic, accessError = youtubeAccess.downloadVideosReferencedInPlaylistForPlaylistUrl(playlistUrl, downloadVideoInfoDic) targetAudioDir = downloadVideoInfoDic.getPlaylistDownloadDir() sys.stdout = stdout self.assertIsNone(accessError) self.assertEqual(['downloading "Wear a mask. Help slow the spread of Covid-19." audio ...', '', '"Wear a mask. Help slow the spread of Covid-19." audio downloaded.', '', '"Test_title_one_time_frame_extract" playlist audio(s) download terminated.', '', ''], outputCapturingString.getvalue().split('\n')) self.assertEqual([[5, 10]], downloadVideoInfoDic.getExtractStartEndSecondsListsForVideoIndex(1)) self.assertEqual(downloadDir, targetAudioDir) self.assertEqual('Wear a mask. Help slow the spread of Covid-19.', downloadVideoInfoDic.getVideoTitleForVideoIndex(1)) self.assertEqual('https://www.youtube.com/watch?v=9iPvLx7gotk', downloadVideoInfoDic.getVideoUrlForVideoIndex(1)) self.assertEqual('https://www.youtube.com/watch?v=9iPvLx7gotk', downloadVideoInfoDic.getVideoUrlForVideoTitle('Wear a mask. Help slow the spread of Covid-19.')) self.assertEqual('Wear a mask. Help slow the spread of Covid-19..mp3', downloadVideoInfoDic.getVideoFileNameForVideoIndex(1)) self.assertEqual('Wear a mask. Help slow the spread of Covid-19..mp3', downloadVideoInfoDic.getVideoFileNameForVideoTitle('Wear a mask. Help slow the spread of Covid-19.')) self.assertEqual(['1'], downloadVideoInfoDic.getVideoIndexes()) if os.name == 'posix': self.assertEqual('/storage/emulated/0/Download/Audiobooks/test/' + playlistName, downloadDir) else: self.assertEqual('D:\\Users\\Jean-Pierre\\Downloads\\Audiobooks\\test\\' + playlistName, downloadDir) fileNameLst = [x.split(DIR_SEP)[-1] for x in glob.glob(downloadDir + DIR_SEP + '*.*')] self.assertEqual(sorted(['Test_title_one_time_frame_extract_dic.txt', 'Wear a mask. Help slow the spread of Covid-19..mp3']), sorted(fileNameLst)) self.assertEqual([[5, 10]], downloadVideoInfoDic.getExtractStartEndSecondsListsForVideoIndex(1))
def testDownloadSingleVideoForUrl_targetFolder_not_exist(self): expectedVideoTitle = 'Funny suspicious looking dog' audioSubDirName = 'Various_test_new' downloadDir = AUDIO_DIR_TEST + DIR_SEP + audioSubDirName # deleting downloadDir (dir and content) if os.path.exists(downloadDir): shutil.rmtree(downloadDir) guiOutput = GuiOutputStub() youtubeAccess = YoutubeDlAudioDownloader(guiOutput, AUDIO_DIR_TEST) videoUrl = "https://youtu.be/vU1NEZ9sTOM" stdout = sys.stdout outputCapturingString = StringIO() sys.stdout = outputCapturingString _, downloadVideoInfoDic, videoTitle, accessError = youtubeAccess.getDownloadVideoInfoDicOrSingleVideoTitleFortUrl( videoUrl) self.assertIsNone(downloadVideoInfoDic) self.assertIsNone(accessError) self.assertEqual(expectedVideoTitle, videoTitle) youtubeAccess.downloadSingleVideoForUrl(videoUrl, videoTitle, downloadDir) sys.stdout = stdout if os.name == 'posix': self.assertEqual([ 'directory', 'Audiobooks/Various_test_new', 'was created.', '', 'downloading "Funny suspicious looking dog" audio ...', '', '"Funny suspicious looking dog" audio downloaded in ' 'test/Various_test_new directory.', '', '' ], outputCapturingString.getvalue().split('\n')) self.assertEqual( '/storage/emulated/0/Download/Audiobooks/test/' + audioSubDirName, downloadDir) else: self.assertEqual([ 'directory', 'test\\Various_test_new', 'was created.', '', 'downloading "Funny suspicious looking dog" audio ...', '', '"Funny suspicious looking dog" audio downloaded in ' 'test\\Various_test_new directory.', '', '' ], outputCapturingString.getvalue().split('\n')) self.assertEqual( 'D:\\Users\\Jean-Pierre\\Downloads\\Audiobooks\\test\\' + audioSubDirName, downloadDir) fileNameLst = [ x.split(DIR_SEP)[-1] for x in glob.glob(downloadDir + DIR_SEP + '*.*') ] self.assertEqual(sorted(['Funny suspicious looking dog.mp3']), sorted(fileNameLst))
def testDownloadVideosReferencedInPlaylistForPlaylistUrl_empty_url(self): guiOutput = GuiOutputStub() youtubeAccess = YoutubeDlAudioDownloader(guiOutput, AUDIO_DIR_TEST) playlistUrl = "" stdout = sys.stdout outputCapturingString = StringIO() sys.stdout = outputCapturingString _, downloadVideoInfoDic, _, accessError = youtubeAccess.getDownloadVideoInfoDicOrSingleVideoTitleFortUrl(playlistUrl) downloadVideoInfoDic, accessError = youtubeAccess.downloadVideosReferencedInPlaylistForPlaylistUrl(playlistUrl, downloadVideoInfoDic) sys.stdout = stdout self.assertEqual('the URL obtained from clipboard is empty.\nnothing to download.', accessError.errorMsg)
def testDownloadVideosReferencedInPlaylistForPlaylistUrl_invalid_url(self): guiOutput = GuiOutputStub() youtubeAccess = YoutubeDlAudioDownloader(guiOutput, AUDIO_DIR_TEST) playlistUrl = "https://www.youtube.com/playlist?list=invalid" stdout = sys.stdout outputCapturingString = StringIO() sys.stdout = outputCapturingString _, downloadVideoInfoDic, _, accessError = youtubeAccess.getDownloadVideoInfoDicOrSingleVideoTitleFortUrl(playlistUrl) downloadVideoInfoDic, accessError = youtubeAccess.downloadVideosReferencedInPlaylistForPlaylistUrl(playlistUrl, downloadVideoInfoDic) sys.stdout = stdout self.assertEqual('trying to get the video title for the URL obtained from clipboard did not succeed.\nfailing URL: https://www.youtube.com/playlist?list=invalid\nerror info: regex_search: could not find match for (?:v=|\/)([0-9A-Za-z_-]{11}).*\nnothing to download.', accessError.errorMsg)
def testDownloadVideosReferencedInPlaylistForPlaylistUrl_targetFolder_not_exist(self): playlistName = 'test_audio_downloader_one_file' downloadDir = AUDIO_DIR_TEST + DIR_SEP + playlistName # deleting downloadDir (dir and content) if os.path.exists(downloadDir): shutil.rmtree(downloadDir) guiOutput = GuiOutputStub() youtubeAccess = YoutubeDlAudioDownloader(guiOutput, AUDIO_DIR_TEST) playlistUrl = "https://www.youtube.com/playlist?list=PLzwWSJNcZTMRxj8f47BrkV9S6WoxYWYDS" stdout = sys.stdout outputCapturingString = StringIO() sys.stdout = outputCapturingString _, downloadVideoInfoDic, _, accessError = youtubeAccess.getDownloadVideoInfoDicOrSingleVideoTitleFortUrl(playlistUrl) youtubeAccess.downloadVideosReferencedInPlaylistForPlaylistUrl(playlistUrl, downloadVideoInfoDic) sys.stdout = stdout if os.name == 'posix': self.assertEqual(['directory', 'test/test_audio_downloader_one_file', 'was created.', '', 'downloading "Wear a mask. Help slow the spread of Covid-19." audio ...', '', '"Wear a mask. Help slow the spread of Covid-19." audio downloaded.', '', ''], outputCapturingString.getvalue().split('\n')) else: self.assertEqual(['directory', 'test\\test_audio_downloader_one_file', 'was created.', '', 'downloading "Wear a mask. Help slow the spread of Covid-19." audio ...', '', '"Wear a mask. Help slow the spread of Covid-19." audio downloaded.', '', '"test_audio_downloader_one_file" playlist audio(s) download terminated.', '', ''], outputCapturingString.getvalue().split('\n')) fileNameLst = [x.split(DIR_SEP)[-1] for x in glob.glob(downloadDir + DIR_SEP + '*.*')] self.assertEqual(sorted(['Wear a mask. Help slow the spread of Covid-19..mp3', 'test_audio_downloader_one_file_dic.txt']), sorted(fileNameLst))
def __init__(self, audioDownloaderGUI, audioDir, configMgr=None): """ :param audioDownloaderGUI: used for unit testing only ! """ if os.name == 'posix': configFilePathName = '/storage/emulated/0/audiodownloader.ini' else: configFilePathName = 'c:\\temp\\audiodownloader.ini' if configMgr == None: self.configMgr = ConfigManager(configFilePathName) else: self.configMgr = configMgr self.requester = Requester(self.configMgr) self.audioDownloaderGUI = audioDownloaderGUI self.audioDownloader = YoutubeDlAudioDownloader(self, audioDir)
def testDownloadSingleVideoForUrl_redownloading_video(self): expectedVideoTitle = 'Funny suspicious looking dog' audioSubDirName = 'Various_test' downloadDir = AUDIO_DIR_TEST + DIR_SEP + audioSubDirName if not os.path.exists(downloadDir): os.mkdir(downloadDir) # deleting files in downloadDir files = glob.glob(downloadDir + DIR_SEP + '*') for f in files: os.remove(f) guiOutput = GuiOutputStub() youtubeAccess = YoutubeDlAudioDownloader(guiOutput, AUDIO_DIR_TEST) videoUrl = "https://youtu.be/vU1NEZ9sTOM" videoUrl = 'https://youtu.be/vU1NEZ9sTOM' _, downloadVideoInfoDic, videoTitle, accessError = youtubeAccess.getDownloadVideoInfoDicOrSingleVideoTitleFortUrl( videoUrl) self.assertIsNone(downloadVideoInfoDic) self.assertIsNone(accessError) self.assertEqual(expectedVideoTitle, videoTitle) youtubeAccess.downloadSingleVideoForUrl(videoUrl, videoTitle, downloadDir) stdout = sys.stdout outputCapturingString = StringIO() sys.stdout = outputCapturingString youtubeAccess.downloadSingleVideoForUrl(videoUrl, videoTitle, downloadDir) sys.stdout = stdout self.assertEqual([ '"Funny suspicious looking dog" audio already downloaded. Video skipped.', '', '' ], outputCapturingString.getvalue().split('\n'))
def testDownloadVideosReferencedInPlaylistForPlaylistUrlMultipleVideo_withTimeFrames_redownloading_the_playlist_after_adding_a_new_video(self): # re-downloading playlist with clearing all files but one in the destination dir # playlist title: test_audio_downloader_two_files_with_time_frames (e0:0:2-0:0:8) (s0:0:2-0:0:5 s0:0:7-0:0:10) playlistName = 'Test 3 short videos' downloadDir = AUDIO_DIR_TEST + DIR_SEP + playlistName if not os.path.exists(downloadDir): os.mkdir(downloadDir) # deleting files in downloadDir files = glob.glob(downloadDir + DIR_SEP + '*') for f in files: os.remove(f) guiOutput = GuiOutputStub() youtubeAccess = YoutubeDlAudioDownloader(guiOutput, AUDIO_DIR_TEST) playlistUrl = 'https://www.youtube.com/playlist?list=PLzwWSJNcZTMShenMgwyjHC8o5bU8QUPbn' stdout = sys.stdout outputCapturingString = StringIO() sys.stdout = outputCapturingString _, downloadVideoInfoDic, _, accessError = youtubeAccess.getDownloadVideoInfoDicOrSingleVideoTitleFortUrl(playlistUrl) downloadVideoInfoDic, accessError = youtubeAccess.downloadVideosReferencedInPlaylistForPlaylistUrl(playlistUrl, downloadVideoInfoDic) sys.stdout = stdout self.assertIsNone(accessError) self.assertEqual( ['downloading "Wear a mask. Help slow the spread of Covid-19." audio ...', '', '"Wear a mask. Help slow the spread of Covid-19." audio downloaded.', '', 'downloading "Here to help: Give him what he wants" audio ...', '', '"Here to help: Give him what he wants" audio downloaded.', '', 'downloading "Funny suspicious looking dog" audio ...', '', '"Funny suspicious looking dog" audio downloaded.', '', '"Test 3 short videos" playlist audio(s) download terminated.', '', ''], outputCapturingString.getvalue().split('\n')) fileNameLst = [x.split(DIR_SEP)[-1] for x in glob.glob(downloadDir + DIR_SEP + '*.*')] self.assertEqual( sorted(['Funny suspicious looking dog.mp3', 'Here to help - Give him what he wants.mp3', 'Test 3 short videos_dic.txt', 'Wear a mask. Help slow the spread of Covid-19..mp3']), sorted(fileNameLst)) # re-downloading the playlist after suppressing the files and data for # the last video # the last video files in downloadDir files = glob.glob(downloadDir + DIR_SEP + '*.mp3') for f in files: if 'Funny suspicious looking dog' in f: os.remove(f) stdout = sys.stdout outputCapturingString = StringIO() sys.stdout = outputCapturingString _, redownloadVideoInfoDic, _, accessError = youtubeAccess.getDownloadVideoInfoDicOrSingleVideoTitleFortUrl(playlistUrl) redownloadVideoInfoDic.removeVideoInfoForVideoTitle('Funny suspicious looking dog') redownloadVideoInfoDic, accessError = youtubeAccess.downloadVideosReferencedInPlaylistForPlaylistUrl( playlistUrl, redownloadVideoInfoDic) targetAudioDir = downloadVideoInfoDic.getPlaylistDownloadDir() sys.stdout = stdout self.assertIsNone(accessError) self.assertEqual(['"Wear a mask. Help slow the spread of Covid-19." audio already downloaded. ' 'Video skipped.', '', '"Here to help: Give him what he wants" audio already downloaded. Video ' 'skipped.', '', 'downloading "Funny suspicious looking dog" audio ...', '', '"Funny suspicious looking dog" audio downloaded.', '', '"Test 3 short videos" playlist audio(s) download terminated.', '', ''], outputCapturingString.getvalue().split('\n')) self.assertEqual(downloadDir, targetAudioDir) self.assertEqual('Wear a mask. Help slow the spread of Covid-19.', redownloadVideoInfoDic.getVideoTitleForVideoIndex(1)) self.assertEqual('https://www.youtube.com/watch?v=9iPvLx7gotk', redownloadVideoInfoDic.getVideoUrlForVideoIndex(1)) self.assertEqual('https://www.youtube.com/watch?v=9iPvLx7gotk', redownloadVideoInfoDic.getVideoUrlForVideoTitle( 'Wear a mask. Help slow the spread of Covid-19.')) self.assertEqual('Wear a mask. Help slow the spread of Covid-19..mp3', redownloadVideoInfoDic.getVideoFileNameForVideoIndex(1)) self.assertEqual('Wear a mask. Help slow the spread of Covid-19..mp3', redownloadVideoInfoDic.getVideoFileNameForVideoTitle( 'Wear a mask. Help slow the spread of Covid-19.')) self.assertEqual('Here to help: Give him what he wants', redownloadVideoInfoDic.getVideoTitleForVideoIndex(2)) self.assertEqual('https://www.youtube.com/watch?v=Eqy6M6qLWGw', redownloadVideoInfoDic.getVideoUrlForVideoIndex(2)) self.assertEqual('https://www.youtube.com/watch?v=Eqy6M6qLWGw', redownloadVideoInfoDic.getVideoUrlForVideoTitle('Here to help: Give him what he wants')) self.assertEqual('Here to help - Give him what he wants.mp3', redownloadVideoInfoDic.getVideoFileNameForVideoIndex(2)) self.assertEqual('Here to help - Give him what he wants.mp3', redownloadVideoInfoDic.getVideoFileNameForVideoTitle( 'Here to help: Give him what he wants')) self.assertEqual('Funny suspicious looking dog', redownloadVideoInfoDic.getVideoTitleForVideoIndex(3)) self.assertEqual('https://www.youtube.com/watch?v=vU1NEZ9sTOM', redownloadVideoInfoDic.getVideoUrlForVideoIndex(3)) self.assertEqual('https://www.youtube.com/watch?v=vU1NEZ9sTOM', redownloadVideoInfoDic.getVideoUrlForVideoTitle('Funny suspicious looking dog')) self.assertEqual('Funny suspicious looking dog.mp3', redownloadVideoInfoDic.getVideoFileNameForVideoIndex(3)) self.assertEqual('Funny suspicious looking dog.mp3', redownloadVideoInfoDic.getVideoFileNameForVideoTitle( 'Funny suspicious looking dog')) fileNameLst = [x.split(DIR_SEP)[-1] for x in glob.glob(downloadDir + DIR_SEP + '*.*')] self.assertEqual( sorted(['Funny suspicious looking dog.mp3', 'Here to help - Give him what he wants.mp3', 'Test 3 short videos_dic.txt', 'Wear a mask. Help slow the spread of Covid-19..mp3']), sorted(fileNameLst))
def testDownloadVideosReferencedInPlaylistForPlaylistUrlMultipleVideo_withTimeFrames_redownloading_the_playlist(self): # playlist title: test_audio_downloader_two_files_with_time_frames (e0:0:2-0:0:8) (s0:0:2-0:0:5 s0:0:7-0:0:10) playlistName = 'test_audio_downloader_two_files_with_time_frames' downloadDir = AUDIO_DIR_TEST + DIR_SEP + playlistName if not os.path.exists(downloadDir): os.mkdir(downloadDir) # deleting files in downloadDir files = glob.glob(downloadDir + DIR_SEP + '*') for f in files: os.remove(f) guiOutput = GuiOutputStub() youtubeAccess = YoutubeDlAudioDownloader(guiOutput, AUDIO_DIR_TEST) playlistUrl = "https://www.youtube.com/playlist?list=PLzwWSJNcZTMSFWGrRGKOypqN29MlyuQvn" stdout = sys.stdout outputCapturingString = StringIO() sys.stdout = outputCapturingString _, downloadVideoInfoDic, _, accessError = youtubeAccess.getDownloadVideoInfoDicOrSingleVideoTitleFortUrl(playlistUrl) downloadVideoInfoDic, accessError = youtubeAccess.downloadVideosReferencedInPlaylistForPlaylistUrl(playlistUrl, downloadVideoInfoDic) targetAudioDir = downloadVideoInfoDic.getPlaylistDownloadDir() sys.stdout = stdout self.assertIsNone(accessError) self.assertEqual( ['downloading "Wear a mask. Help slow the spread of Covid-19." audio ...', '', '"Wear a mask. Help slow the spread of Covid-19." audio downloaded.', '', 'downloading "Here to help: Give him what he wants" audio ...', '', '"Here to help: Give him what he wants" audio downloaded.', '', '"test_audio_downloader_two_files_with_time_frames" playlist audio(s) download terminated.', '', ''], outputCapturingString.getvalue().split('\n')) # playlist title: test_audio_downloader_two_files_with_time_frames # (e0:0:2-0:0:8) (s0:0:2-0:0:5 s0:0:7-0:0:10) startEndSecondsList_extract_firstVideo_firstTimeFrame = [2, 8] startEndSecondsList_suppress_secondVideo_firstTimeFrame = [2, 5] startEndSecondsList_suppress_secondVideo_secondTimeFrame = [7, 10] self.assertEqual([startEndSecondsList_extract_firstVideo_firstTimeFrame], downloadVideoInfoDic.getExtractStartEndSecondsListsForVideoIndex(1)) self.assertEqual([], downloadVideoInfoDic.getSuppressStartEndSecondsListsForVideoIndex(1)) self.assertEqual([], downloadVideoInfoDic.getExtractStartEndSecondsListsForVideoIndex(2)) self.assertEqual([startEndSecondsList_suppress_secondVideo_firstTimeFrame, startEndSecondsList_suppress_secondVideo_secondTimeFrame], downloadVideoInfoDic.getSuppressStartEndSecondsListsForVideoIndex(2)) self.assertEqual(downloadDir, targetAudioDir) self.assertEqual('Wear a mask. Help slow the spread of Covid-19.', downloadVideoInfoDic.getVideoTitleForVideoIndex(1)) self.assertEqual('https://www.youtube.com/watch?v=9iPvLx7gotk', downloadVideoInfoDic.getVideoUrlForVideoIndex(1)) self.assertEqual('https://www.youtube.com/watch?v=9iPvLx7gotk', downloadVideoInfoDic.getVideoUrlForVideoTitle( 'Wear a mask. Help slow the spread of Covid-19.')) self.assertEqual('Wear a mask. Help slow the spread of Covid-19..mp3', downloadVideoInfoDic.getVideoFileNameForVideoIndex(1)) self.assertEqual('Wear a mask. Help slow the spread of Covid-19..mp3', downloadVideoInfoDic.getVideoFileNameForVideoTitle( 'Wear a mask. Help slow the spread of Covid-19.')) self.assertEqual('Here to help: Give him what he wants', downloadVideoInfoDic.getVideoTitleForVideoIndex(2)) self.assertEqual('https://www.youtube.com/watch?v=Eqy6M6qLWGw', downloadVideoInfoDic.getVideoUrlForVideoIndex(2)) self.assertEqual('https://www.youtube.com/watch?v=Eqy6M6qLWGw', downloadVideoInfoDic.getVideoUrlForVideoTitle('Here to help: Give him what he wants')) self.assertEqual('Here to help - Give him what he wants.mp3', downloadVideoInfoDic.getVideoFileNameForVideoIndex(2)) self.assertEqual('Here to help - Give him what he wants.mp3', downloadVideoInfoDic.getVideoFileNameForVideoTitle( 'Here to help: Give him what he wants')) self.assertEqual(['1', '2'], downloadVideoInfoDic.getVideoIndexes()) fileNameLst = [x.split(DIR_SEP)[-1] for x in glob.glob(downloadDir + DIR_SEP + '*.*')] self.assertEqual( sorted(['Here to help - Give him what he wants.mp3', 'Wear a mask. Help slow the spread of Covid-19..mp3', 'test_audio_downloader_two_files_with_time_frames_dic.txt']), sorted(fileNameLst)) # re-downloading the playlist youtubeAccess_redownload = YoutubeDlAudioDownloader(guiOutput, AUDIO_DIR_TEST) stdout = sys.stdout outputCapturingString = StringIO() sys.stdout = outputCapturingString _, redownloadVideoInfoDic, _, accessError = youtubeAccess.getDownloadVideoInfoDicOrSingleVideoTitleFortUrl(playlistUrl) redownloadVideoInfoDic, accessError = youtubeAccess.downloadVideosReferencedInPlaylistForPlaylistUrl(playlistUrl, redownloadVideoInfoDic) targetAudioDir = downloadVideoInfoDic.getPlaylistDownloadDir() sys.stdout = stdout self.assertIsNone(accessError) self.assertEqual(['"Wear a mask. Help slow the spread of Covid-19." audio already downloaded. ' 'Video skipped.', '', '"Here to help: Give him what he wants" audio already downloaded. Video ' 'skipped.', '', '"test_audio_downloader_two_files_with_time_frames" playlist audio(s) ' 'download terminated.', '', ''], outputCapturingString.getvalue().split('\n')) self.assertEqual([startEndSecondsList_extract_firstVideo_firstTimeFrame], redownloadVideoInfoDic.getExtractStartEndSecondsListsForVideoIndex(1)) self.assertEqual([], redownloadVideoInfoDic.getSuppressStartEndSecondsListsForVideoIndex(1)) self.assertEqual([], redownloadVideoInfoDic.getExtractStartEndSecondsListsForVideoIndex(2)) self.assertEqual([startEndSecondsList_suppress_secondVideo_firstTimeFrame, startEndSecondsList_suppress_secondVideo_secondTimeFrame], redownloadVideoInfoDic.getSuppressStartEndSecondsListsForVideoIndex(2)) self.assertEqual(downloadDir, targetAudioDir) self.assertEqual('Wear a mask. Help slow the spread of Covid-19.', redownloadVideoInfoDic.getVideoTitleForVideoIndex(1)) self.assertEqual('https://www.youtube.com/watch?v=9iPvLx7gotk', redownloadVideoInfoDic.getVideoUrlForVideoIndex(1)) self.assertEqual('https://www.youtube.com/watch?v=9iPvLx7gotk', redownloadVideoInfoDic.getVideoUrlForVideoTitle( 'Wear a mask. Help slow the spread of Covid-19.')) self.assertEqual('Wear a mask. Help slow the spread of Covid-19..mp3', redownloadVideoInfoDic.getVideoFileNameForVideoIndex(1)) self.assertEqual('Wear a mask. Help slow the spread of Covid-19..mp3', redownloadVideoInfoDic.getVideoFileNameForVideoTitle( 'Wear a mask. Help slow the spread of Covid-19.')) self.assertEqual('Here to help: Give him what he wants', redownloadVideoInfoDic.getVideoTitleForVideoIndex(2)) self.assertEqual('https://www.youtube.com/watch?v=Eqy6M6qLWGw', redownloadVideoInfoDic.getVideoUrlForVideoIndex(2)) self.assertEqual('https://www.youtube.com/watch?v=Eqy6M6qLWGw', redownloadVideoInfoDic.getVideoUrlForVideoTitle('Here to help: Give him what he wants')) self.assertEqual('Here to help - Give him what he wants.mp3', redownloadVideoInfoDic.getVideoFileNameForVideoIndex(2)) self.assertEqual('Here to help - Give him what he wants.mp3', redownloadVideoInfoDic.getVideoFileNameForVideoTitle( 'Here to help: Give him what he wants')) self.assertEqual(['1', '2'], redownloadVideoInfoDic.getVideoIndexes()) fileNameLst = [x.split(DIR_SEP)[-1] for x in glob.glob(downloadDir + DIR_SEP + '*.*')] self.assertEqual( sorted(['Here to help - Give him what he wants.mp3', 'Wear a mask. Help slow the spread of Covid-19..mp3', 'test_audio_downloader_two_files_with_time_frames_dic.txt']), sorted(fileNameLst))
class AudioController: def __init__(self, audioDownloaderGUI, audioDir, configMgr=None): """ :param audioDownloaderGUI: used for unit testing only ! """ if os.name == 'posix': configFilePathName = '/storage/emulated/0/audiodownloader.ini' else: configFilePathName = 'c:\\temp\\audiodownloader.ini' if configMgr == None: self.configMgr = ConfigManager(configFilePathName) else: self.configMgr = configMgr self.requester = Requester(self.configMgr) self.audioDownloaderGUI = audioDownloaderGUI self.audioDownloader = YoutubeDlAudioDownloader(self, audioDir) def downloadVideosReferencedInPlaylistOrSingleVideo( self, url, downloadVideoInfoDic, singleVideoTitle): ''' In case we are downloading videos referenced in a playlist, this method first execute the download of the audio of the videos and then execute the extraction or suppression of audio parts as specified in the playlist title, this, provided we are on Windows (extraction/suppression are not supported on Android). Example of playlist title: playlist_title (s01:05:52-01:07:23 e01:15:52-E E01:35:52-01:37:23 S01:25:52-e) (s01:05:52-01:07:23 e01:15:52-e S01:25:52-e E01:35:52-01:37:23) -e or -E means "to end" ! If we are downloading a single video audio, no extraction/suppression will be performed. :param url: playlist or single video url :param downloadVideoInfoDic: if url points to a playlist :param singleVideoTitle: if the url points to a single video ''' if downloadVideoInfoDic: # downloading the audio track of the videos referenced in the playlist _, accessError = self.audioDownloader.downloadVideosReferencedInPlaylistForPlaylistUrl( url, downloadVideoInfoDic) # extracting/suppressing the audio portions for the downloaded audio tracks if accessError is None: if os.name == 'posix': msgText = 'skipping extraction/suppression on Android.\n' self.displayMessage(msgText) else: # extraction/suppression possible only on Windows ! targetAudioDir = downloadVideoInfoDic.getPlaylistDownloadDir( ) audioExtractor = AudioExtractor(self, targetAudioDir, downloadVideoInfoDic) audioExtractor.extractPlaylistAudio(downloadVideoInfoDic) # saving the content of the downloadVideoInfoDic which has been completed # by AudioExtractor in the directory containing the extracted audio files try: downloadVideoInfoDic.saveDic() except TypeError as e: print(e) traceback.print_exc() else: # downloading a single video self.audioDownloader.downloadSingleVideoForUrl( url, singleVideoTitle, self.audioDownloaderGUI.singleVideoDownloadDir) def trimAudioFile(self, audioFilePathName): """ Example of command line: audiodownload.py filePathName e0:0:2-e e0:0:3-e audiodownload filePathName e0:0:2-0:10:55 e0:0:3-0:10:53 :param audioFilePathName: :return: """ audioFileName = audioFilePathName.split(DIR_SEP)[-1] audioFileDir = audioFilePathName.replace(DIR_SEP + audioFileName, '') # initializing a partially filled DownloadVideoInfoDic with only the informations # required to trim the audio file downloadVideoInfoDic = DownloadVideoInfoDic(audioFileDir) downloadVideoInfoDic.addVideoInfoForVideoIndex( 1, audioFileName.split('.')[0], '', audioFileName) # getting the extract time frames specified as command line argument # and adding them to the DownloadVideoInfoDic extractStartEndSecondsLists = self.requester.getExtractStartEndSecondsLists( ) for extractStartEndSecondsList in extractStartEndSecondsLists: downloadVideoInfoDic.addExtractStartEndSecondsListForVideoIndex( 1, extractStartEndSecondsList) # now trimming the audio file audioExtractor = AudioExtractor(self, audioFileDir, downloadVideoInfoDic) audioExtractor.extractAudioPortions(1, audioFileName, downloadVideoInfoDic) def getDownloadVideoInfoDicOrSingleVideoTitleFortUrl(self, url): """ As the passed URL points either to a playlist or to a single video, the method returns either a DownloadVideoInfoDic in case of playlist URL or None and a video title in case of single video URL. :param url: playlist or single video url :return: downloadVideoInfoDic, videoTitle """ _, downloadVideoInfoDic, videoTitle, accessError = self.audioDownloader.getDownloadVideoInfoDicOrSingleVideoTitleFortUrl( url) if accessError: self.displayMessage(accessError.errorMsg) return None, None return downloadVideoInfoDic, videoTitle def displayMessage(self, msgText): self.audioDownloaderGUI.outputResult(msgText) def displayError(self, msg): self.audioDownloaderGUI.outputResult(msg) def getConfirmation(self, title, msg): return self.audioDownloaderGUI.getConfirmation(title, msg) # method temporary here. Will be suppressed ! def getPrintableResultForInput(self, inputStr, copyResultToClipboard=True): ''' Return the printable request result, the full request command without any command option and the full request command with any specified save mode option (option which is to be saved in the command history list. :param inputStr: :param copyResultToClipboard: set to True by default. Whreplaying all requests stored in history, set to False, which avoids problem on Android :seqdiag_return printResult, fullCommandStrNoOptions, fullCommandStrWithOptions, fullCommandStrWithSaveModeOptions :return: 1/ printable request result 2/ full request command without any command option 3/ full request command with any non save command option 4/ full request command with any specified save mode option, None if no save mode option is in effect Ex: 1/ 0.1 ETH/36 USD on Bitfinex: 21/11/17 10:00 360 2/ eth usd 0 bitfinex 3/ None (value command with save mode in effect !) 4/ eth usd 0 bitfinex -vs0.1eth 1/ 0.1 ETH/36 USD on Bitfinex: 21/11/17 10:00 360 2/ eth usd 0 bitfinex 3/ eth usd 0 bitfinex -v0.1eth 4/ None (no value command save option in effect) 1/ ETH/USD on Bitfinex: 21/11/17 10:00 360 2/ eth usd 0 bitfinex 3/ None (no value command in effect) 4/ None (no value command save option in effect) ''' return inputStr, inputStr, inputStr, inputStr, inputStr
def testDownloadSingleVideoForUrl_succeed_on_Windows_only(self): """ As unit test, works on Android although the downloaded file is not fully valid: can be played, but without setting position. """ expectedVideoTitle = 'Is NEO Worth Buying? - Price Prediction 2020/2021 🚀🚀🚀' audioSubDirName = 'Various_test' downloadDir = AUDIO_DIR_TEST + DIR_SEP + audioSubDirName if not os.path.exists(downloadDir): os.mkdir(downloadDir) # deleting files in downloadDir files = glob.glob(downloadDir + DIR_SEP + '*') for f in files: os.remove(f) guiOutput = GuiOutputStub() youtubeAccess = YoutubeDlAudioDownloader(guiOutput, AUDIO_DIR_TEST) videoUrl = "https://youtu.be/LhH9uX3kgTI" stdout = sys.stdout outputCapturingString = StringIO() sys.stdout = outputCapturingString _, downloadVideoInfoDic, videoTitle, accessError = youtubeAccess.getDownloadVideoInfoDicOrSingleVideoTitleFortUrl( videoUrl) self.assertIsNone(downloadVideoInfoDic) self.assertIsNone(accessError) self.assertEqual(expectedVideoTitle, videoTitle) youtubeAccess.downloadSingleVideoForUrl(videoUrl, videoTitle, downloadDir) sys.stdout = stdout if os.name == 'posix': self.assertEqual([ 'downloading "Is NEO Worth Buying? - Price Prediction 2020/2021 🚀🚀🚀" audio ' '...', '', '"Is NEO Worth Buying? - Price Prediction 2020/2021 🚀🚀🚀" audio downloaded in ' 'test/Various_test directory.', '', '' ], outputCapturingString.getvalue().split('\n')) else: self.assertEqual([ 'downloading "Is NEO Worth Buying? - Price Prediction 2020/2021 🚀🚀🚀" audio ' '...', '', '"Is NEO Worth Buying? - Price Prediction 2020/2021 🚀🚀🚀" audio downloaded in ' 'test\\Various_test directory.', '', '' ], outputCapturingString.getvalue().split('\n')) if os.name == 'posix': self.assertEqual( '/storage/emulated/0/Download/Audiobooks/test/' + audioSubDirName, downloadDir) else: self.assertEqual( 'D:\\Users\\Jean-Pierre\\Downloads\\Audiobooks\\test\\' + audioSubDirName, downloadDir) fileNameLst = [ x.split(DIR_SEP)[-1] for x in glob.glob(downloadDir + DIR_SEP + '*.*') ] self.assertEqual( sorted([ 'Is NEO Worth Buying - Price Prediction 2020_2021 🚀🚀🚀.mp3' ]), sorted(fileNameLst))