I am trying to have a function that gets the name of a newly downloaded file run in the background while I run another program that downloads a specific file. The background function will have a return value of the newly downloaded file which I plan to utilize in the code later on. I have the rough framework of what I am trying to do below.
with concurrent.futures.ThreadPoolExecutor(max_workers = 1) as executor:
output = executor.submit(downloadedfiledetector, filedirectory)
filename = output.result()
#Run code that will download a file
print(filename)
Here, downloadedfiledetector is the function that returns the directory of the file that is downloaded and filedirectory is the argument to that function containing the file path that the function will watch. I want the return value to be stored in the filename variable so that I can then utilize it later on in the program. Then below that, I run more code that essentially downloads a file from a website where the name of the file will be different everytime (hence the need for a function that grabs the name of a newly downloaded file).
When I run the above code, it simply does not run the code that downloads the file and only runs the downloadedfiledetector function. Any help is appreciated!
Edit: I was asked to include a working example of the code. I know it is for sure not the best way to do this, but I wrote it myself (for the most part) and I'm still pretty new to Python. At the bottom of the code, the combinesubtitletovideo function is where I will use the downloaded .srt file and combine it with a video:
import os
import time
from selenium.webdriver.common.by import By
import undetected_chromedriver as bypass
import concurrent.futures
def downloadedfiledetector(scannedfolder, variablefunction):
seconds = 0
dl_wait = True
filelist1 = []
filelist2 = []
while dl_wait and seconds < 120:
for fname in os.listdir(scannedfolder):
filelist1.append(fname)
if fname.endswith('.crdownload') and seconds != 0:
filelist1.pop()
time.sleep(1)
for fname in os.listdir(scannedfolder):
filelist2.append(fname)
if fname.endswith('.crdownload') and seconds != 0:
filelist2.pop()
if seconds != 0 and len(filelist1) != len(filelist2):
dl_wait = False
seconds = 1
if variablefunction == 1:
newfilename1 = list(set(filelist2) - set(filelist1))
newfilename2 = ''.join(str(e) for e in newfilename1)
time.sleep(1)
driver.close()
return newfilename2
elif variablefunction == 2:
pass
with concurrent.futures.ThreadPoolExecutor(max_workers = 1) as executor:
output = executor.submit(downloadedfiledetector, cliplocation, 1)
filenamesubtitle = output.result()
driver = bypass.Chrome(options=options)
driver.get(subtitleurl)
WebDriverWait(driver, 300).until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#root > section > section.container.mx-auto.py-6.mt-4.sm\:mt-6 > div.mx-auto.max-w-4xl.leading-normal.mt-6.sm\:mt-10.sm\:flex.justify-center.px-4.lg\:px-0.text-center > div > div > div > input')))
enterurlbox = driver.find_element(By.CSS_SELECTOR, '#root > section > section.container.mx-auto.py-6.mt-4.sm\:mt-6 > div.mx-auto.max-w-4xl.leading-normal.mt-6.sm\:mt-10.sm\:flex.justify-center.px-4.lg\:px-0.text-center > div > div > div > input')
enterurlbox.send_keys(youtubeurl)
WebDriverWait(driver, 300).until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#root > section > section.container.mx-auto.py-6.mt-4.sm\:mt-6 > div.mx-auto.max-w-4xl.leading-normal.mt-6.sm\:mt-10.sm\:flex.justify-center.px-4.lg\:px-0.text-center > button')))
downloadbutton = driver.find_element(By.CSS_SELECTOR, '#root > section > section.container.mx-auto.py-6.mt-4.sm\:mt-6 > div.mx-auto.max-w-4xl.leading-normal.mt-6.sm\:mt-10.sm\:flex.justify-center.px-4.lg\:px-0.text-center > button')
downloadbutton.click()
WebDriverWait(driver, 300).until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#root > section > main > section.max-w-3xl.mx-auto.md\:flex.md\:justify-between.pt-4 > div.w-full.px-4.lg\:px-0.mb-6.md\:mb-0 > ul > li.py-6.text-center.block.w-full.px-2.sm\:px-4.sm\:py-3.sm\:flex.justify-between.items-center.border-b.border-gray-200.dark\:border-night-500 > section > div > div > a:nth-child(1)')))
srtdownloadbutton = driver.find_element(By.CSS_SELECTOR, '#root > section > main > section.max-w-3xl.mx-auto.md\:flex.md\:justify-between.pt-4 > div.w-full.px-4.lg\:px-0.mb-6.md\:mb-0 > ul > li.py-6.text-center.block.w-full.px-2.sm\:px-4.sm\:py-3.sm\:flex.justify-between.items-center.border-b.border-gray-200.dark\:border-night-500 > section > div > div > a:nth-child(1)')
srtdownloadbutton.click()
time.sleep(2)
combinesubtitletovideo(filenamesubtitle)
CodePudding user response:
You can use map functionality that returns the result from the target function :
with concurrent.futures.ThreadPoolExecutor(max_workers = 1) as executor:
for result in executor.map(downloadedfiledetector, filedirectory):
print(result) #this gives you the required return value from function
CodePudding user response:
It looks like you are using the concurrent.futures module to run the downloadedfiledetector function in a separate thread while your main program continues to run. However, it looks like you are calling output.result() right after you submit the task, which will block the main program until the task completes. This is why it seems like the main program is not running the code that downloads the file.
To fix this, you can move the call to output.result() to a later point in the main program, after the code that downloads the file has been executed. This will allow the main program to continue running and execute the code that downloads the file, while the downloadedfiledetector function is running in the background. You can then use the result() method at a later point to get the result of the task when you are ready to use it.
with concurrent.futures.ThreadPoolExecutor(max_workers = 1) as executor:
output = executor.submit(downloadedfiledetector, filedirectory)
# Run code that will download a file
# Wait for the downloadedfiledetector task to complete and get the result
filename = output.result()
print(filename)
This way, the main program will run the code that downloads the file, and then wait for the downloadedfiledetector task to complete before printing the filename variable.
I hope this helps! Let me know if you have any questions.