Download file
Download file
When downloading files from the Internet via RPA, there is often a problem: It is necessary to understand when the download is complete. Here is an example of how such functionality can be implemented.
Below is the code of the waitFile() method from the task class. This method, using the NIO2 API, waits for the file to be created in the directory for downloading. The complete code of the class, as well as other classes required to test its work are given below.
waitFile method
private String waitFile(int timeoutSeconds) throws IOException { Path directory = Paths.get(filePath); try (WatchService service = directory.getFileSystem().newWatchService()) { directory.register(service, StandardWatchEventKinds.ENTRY_CREATE); long timeout = TimeUnit.NANOSECONDS.convert(timeoutSeconds, TimeUnit.SECONDS); while (timeout > 0L) { final long start = System.nanoTime(); WatchKey key = service.poll(timeout, TimeUnit.NANOSECONDS); if (key != null) { for (WatchEvent<?> event : key.pollEvents()) { Path path = (Path) event.context(); if (path.toString().toLowerCase().endsWith(FILE_EXTENSION)) { return path.getFileName().toString(); } } key.reset(); timeout -= System.nanoTime() - start; } else { break; } } } catch (InterruptedException ignore) { } return null; }
Using the ChromeOptions class, we pass parameters that allow you to start downloading to the specified directory without a dialog window appearing. An example of interaction with such a window can be found in the Upload file article.
DownloadFile.java
package eu.ibagroup.easyrpa.filedownload.task; import eu.ibagroup.easyrpa.engine.annotation.ApTaskEntry; import eu.ibagroup.easyrpa.engine.annotation.Configuration; import eu.ibagroup.easyrpa.engine.annotation.Driver; import eu.ibagroup.easyrpa.engine.annotation.DriverParameter; import eu.ibagroup.easyrpa.engine.apflow.ApTask; import eu.ibagroup.easyrpa.engine.rpa.driver.BrowserDriver; import eu.ibagroup.easyrpa.engine.rpa.driver.DriverParams; import eu.ibagroup.easyrpa.filedownload.WebApplication; import eu.ibagroup.easyrpa.filedownload.page.MainPage; import lombok.extern.slf4j.Slf4j; import org.openqa.selenium.Capabilities; import org.openqa.selenium.chrome.ChromeOptions; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardWatchEventKinds; import java.nio.file.WatchEvent; import java.nio.file.WatchKey; import java.nio.file.WatchService; import java.util.HashMap; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; @ApTaskEntry(name = "Download file") @Slf4j public class DownloadFile extends ApTask { private static final String FILE_EXTENSION = ".bin"; @Driver(param = { @DriverParameter(key = DriverParams.Browser.SELENIUM_NODE_CAPABILITIES, initializerName = DriverParams.BrowserCapabilities.CHROME) }) private BrowserDriver browserDriver; @Configuration(value = "hetzner.app.url", defaultValue = "https://speed.hetzner.de/") private String url; private static final String filePath = System.getProperty("user.home") + "\\Downloads"; // hetzner.file.path public static final class ChromeInitializer implements Supplier<Capabilities> { @Override public Capabilities get() { ChromeOptions chromeOptions = new ChromeOptions(); HashMap<String, Object> chromePrefs = new HashMap<>(); chromePrefs.put("profile.default_content_settings.popups", 0); chromePrefs.put("download.default_directory", filePath); chromeOptions.setExperimentalOption("prefs", chromePrefs); return chromeOptions; } } @Override public void execute() { WebApplication webApplication = new WebApplication(browserDriver); MainPage mainPage = webApplication.open(url); mainPage.dovnloadTestFile(); String downloadedFileName = null; try { downloadedFileName = waitFile(500); } catch (IOException e) { // do something } if (downloadedFileName != null) { log.info("Downloaded file name: " + downloadedFileName); } else { log.info("File wasn't downloaded! "); } } private String waitFile(int timeoutSeconds) throws IOException { Path directory = Paths.get(filePath); try (WatchService service = directory.getFileSystem().newWatchService()) { directory.register(service, StandardWatchEventKinds.ENTRY_CREATE); long timeout = TimeUnit.NANOSECONDS.convert(timeoutSeconds, TimeUnit.SECONDS); while (timeout > 0L) { final long start = System.nanoTime(); WatchKey key = service.poll(timeout, TimeUnit.NANOSECONDS); if (key != null) { for (WatchEvent<?> event : key.pollEvents()) { Path path = (Path) event.context(); if (path.toString().toLowerCase().endsWith(FILE_EXTENSION)) { return path.getFileName().toString(); } } key.reset(); timeout -= System.nanoTime() - start; } else { break; } } } catch (InterruptedException ignore) { } return null; } }