From bb75899bb939cdc1d41b5a6824c0ad75b57d8aba Mon Sep 17 00:00:00 2001 From: xeviff Date: Thu, 13 Apr 2023 19:21:42 +0200 Subject: [PATCH] some improvements, including work directly with production jobs --- pom.xml | 2 +- .../config/LocalEnvironmentManager.java | 28 ++++- src/main/java/tv/mangrana/jobs/JobFile.java | 2 +- .../java/tv/mangrana/jobs/JobFileManager.java | 15 ++- .../plex/url/PlexCommandLauncher.java | 40 +++++-- src/main/java/tv/mangrana/utils/Output.java | 2 +- .../java/tv/mangrana/utils/RetryEngine.java | 108 ++++++++++++++++++ 7 files changed, 177 insertions(+), 20 deletions(-) create mode 100644 src/main/java/tv/mangrana/utils/RetryEngine.java diff --git a/pom.xml b/pom.xml index 79203dd..ed38ecf 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ tv.mangrana mangrana-commons - 1.0-SNAPSHOT + 3.0 8 diff --git a/src/main/java/tv/mangrana/config/LocalEnvironmentManager.java b/src/main/java/tv/mangrana/config/LocalEnvironmentManager.java index f960036..4733369 100644 --- a/src/main/java/tv/mangrana/config/LocalEnvironmentManager.java +++ b/src/main/java/tv/mangrana/config/LocalEnvironmentManager.java @@ -5,10 +5,28 @@ import org.apache.commons.lang.StringUtils; public class LocalEnvironmentManager { - private LocalEnvironmentManager(){} + public enum LocalMode {NAS, PC, CONTABO} + + static LocalMode mode; + static { + mode = LocalMode.PC; + } public static final String PROJECT_ROOT = System.getProperty("user.dir"); + public static final String REMOTE_ACCESS_FOLDER_FROM_MAC = "Volumes"; + + public static void setLocalMode(String mode) { + try { + LocalEnvironmentManager.mode = LocalMode.valueOf(mode); + } catch (IllegalArgumentException ignored) { + } + } + + public static String getRootPath() { + return mode.equals(LocalMode.PC) ? PROJECT_ROOT : REMOTE_ACCESS_FOLDER_FROM_MAC; + } + public static boolean isLocal () { String envVar = System.getenv("ENV"); return @@ -16,4 +34,12 @@ public class LocalEnvironmentManager { && envVar.equals("local"); } + public static boolean isWorkingWithProdFiles () { + return mode.equals(LocalMode.CONTABO) || !isLocal(); + } + + public static LocalMode getLocalMode() { + return mode; + } + } diff --git a/src/main/java/tv/mangrana/jobs/JobFile.java b/src/main/java/tv/mangrana/jobs/JobFile.java index 99c295a..761e8a1 100644 --- a/src/main/java/tv/mangrana/jobs/JobFile.java +++ b/src/main/java/tv/mangrana/jobs/JobFile.java @@ -23,7 +23,7 @@ public abstract class JobFile { return getLocalNameIfNecessary(this); } private String getLocalNameIfNecessary(JobLocation location) { - if (LocalEnvironmentManager.isLocal() + if (LocalEnvironmentManager.isLocal() && !LocalEnvironmentManager.isWorkingWithProdFiles() && (location.equals(JobLocation.PATH_TODO) || location.equals(JobLocation.PATH_DOING))) { return LOCAL_WORKING_PATH; } diff --git a/src/main/java/tv/mangrana/jobs/JobFileManager.java b/src/main/java/tv/mangrana/jobs/JobFileManager.java index 210e99c..af370a8 100644 --- a/src/main/java/tv/mangrana/jobs/JobFileManager.java +++ b/src/main/java/tv/mangrana/jobs/JobFileManager.java @@ -10,7 +10,7 @@ import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -import static tv.mangrana.config.LocalEnvironmentManager.PROJECT_ROOT; +import static tv.mangrana.config.LocalEnvironmentManager.getLocalMode; import static tv.mangrana.jobs.JobFile.JobLocation; import static tv.mangrana.jobs.JobFile.JobLocation.PATH_DOING; import static tv.mangrana.jobs.JobFile.JobLocation.PATH_TODO; @@ -21,12 +21,14 @@ public class JobFileManager { private JobFileManager(){} - public static final String JOBS_FOLDER = "jobs"; + static final String JOBS_FOLDER = "jobs"; + static final String ALT_JOBS_FOLDER = "jobs-1"; public enum JobFileType { SONARR_JOBS("sonarr"), RADARR_JOBS("radarr"), TRANSMISSION_JOBS("transm"); + private final String folderName; JobFileType(String folderName) { this.folderName=folderName; @@ -35,7 +37,6 @@ public class JobFileManager { return folderName; } } - public static void moveUncompletedJobsToRetry(JobFileType appType) { File jobsDir = new File(getAbsolutePath(PATH_DOING, appType)); File[] files = jobsDir.listFiles(); @@ -64,10 +65,16 @@ public class JobFileManager { public static String getAbsolutePath(JobLocation location, JobFileType appType) { String jobsFolder = LocalEnvironmentManager.isLocal() - ? addSubFolder(rootFolder(PROJECT_ROOT), JOBS_FOLDER) + ? addSubFolder(rootFolder(LocalEnvironmentManager.getRootPath()), getLocalJobsFolder()) : rootFolder(JOBS_FOLDER); String appFolderPath = addSubFolder(jobsFolder, appType.getFolderName()); return addSubFolder(appFolderPath, location.getFolderName()); } + + static String getLocalJobsFolder() { + return getLocalMode().equals(LocalEnvironmentManager.LocalMode.CONTABO) + ? ALT_JOBS_FOLDER + : JOBS_FOLDER; + } } diff --git a/src/main/java/tv/mangrana/plex/url/PlexCommandLauncher.java b/src/main/java/tv/mangrana/plex/url/PlexCommandLauncher.java index 4cb7fee..6b61969 100644 --- a/src/main/java/tv/mangrana/plex/url/PlexCommandLauncher.java +++ b/src/main/java/tv/mangrana/plex/url/PlexCommandLauncher.java @@ -40,16 +40,25 @@ public class PlexCommandLauncher { // new PlexCommandLauncher(new CommonConfigFileLoader()).scanByPath(toRefresh); // } - public void scanSerieByPath(String fullDestinationPath) { - scanByPath(getPlexSeriePath2Refresh(fullDestinationPath)); + public boolean scanSerieByPath(String fullDestinationPath) { + try { + return scanByPath(getPlexSeriePath2Refresh(fullDestinationPath)); + } catch (Exception e) { + return false; + } } - public void scanMovieByPath(String fullDestinationPath) { - scanByPath(getPlexMoviePath2Refresh(fullDestinationPath)); + public boolean scanMovieByPath(String fullDestinationPath) { + try { + return scanByPath(getPlexMoviePath2Refresh(fullDestinationPath)); + } catch (Exception e) { + return false; + } } - private void scanByPath(String plexPathToRefresh) { + private boolean scanByPath(String plexPathToRefresh) { + boolean ok = true; String plexRefreshURL = getPlexRefreshURL(plexPathToRefresh); - if (plexRefreshURL==null) return; + if (plexRefreshURL==null) return false; try (CloseableHttpClient httpclient = HttpClients.createDefault()) { HttpUriRequest httpGET = RequestBuilder.get() @@ -64,7 +73,9 @@ public class PlexCommandLauncher { } catch (Exception e) { logger.nHLog("Some error has happened using the URL <{0}>", plexRefreshURL); e.printStackTrace(); + ok = false; } + return ok; } public String getPlexSeriePath2Refresh(String fullDestinationPath) { @@ -85,6 +96,7 @@ public class PlexCommandLauncher { .setUri(new URI(plexSectionsURL)) .addParameter("X-Plex-Token", config.getConfig(PLEX_TOKEN)) .build(); + try (CloseableHttpResponse httpResponse = httpclient.execute(httpGET)) { final HttpEntity entity = httpResponse.getEntity(); @@ -107,12 +119,16 @@ public class PlexCommandLauncher { } private String getPlexRefreshURL(String fullDestinationPath) { - String sectionId = sectionResolver.resolveSectionByPath(fullDestinationPath); - if (sectionId==null) return null; - String host = config.getConfig(PLEX_HOST); - String uriFormat = config.getConfig(PLEX_SECTION_REFRESH_URI); - String uri = uriFormat.replaceFirst("\\{section_id}", sectionId); - return HTTPS.getMark() + host + uri; + try { + String sectionId = sectionResolver.resolveSectionByPath(fullDestinationPath); + if (sectionId==null) return null; + String host = config.getConfig(PLEX_HOST); + String uriFormat = config.getConfig(PLEX_SECTION_REFRESH_URI); + String uri = uriFormat.replaceFirst("\\{section_id}", sectionId); + return HTTPS.getMark() + host + uri; + } catch (Exception e) { + return null; + } } private String getPlexSectionsURL() { diff --git a/src/main/java/tv/mangrana/utils/Output.java b/src/main/java/tv/mangrana/utils/Output.java index 3de2b64..e175ee0 100644 --- a/src/main/java/tv/mangrana/utils/Output.java +++ b/src/main/java/tv/mangrana/utils/Output.java @@ -16,7 +16,7 @@ public class Output { } public static void log (String msg, Object... params) { try { - if (params.length>1) + if (params.length>0) log(msg(msg, params)); else log(msg); diff --git a/src/main/java/tv/mangrana/utils/RetryEngine.java b/src/main/java/tv/mangrana/utils/RetryEngine.java new file mode 100644 index 0000000..55f0190 --- /dev/null +++ b/src/main/java/tv/mangrana/utils/RetryEngine.java @@ -0,0 +1,108 @@ +package tv.mangrana.utils; + +import tv.mangrana.exception.TooMuchTriesException; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; + +import static tv.mangrana.utils.Output.getCurrentTime; +import static tv.mangrana.utils.Output.msg; +import static tv.mangrana.utils.Waiter.waitMinutes; +import static tv.mangrana.utils.Waiter.waitSeconds; + +public class RetryEngine { + + private final String title; + private final int minutesToWait; + private final ChildrenRequirements childrenRequirements; + private final Consumer logger; + + public static class ChildrenRequirements { + final int children; + final Function> retriever; + final Function constraint; + final int childrenLookupMaxRetries; + + public ChildrenRequirements(int childrenMustHave, Function> childrenRetriever, Function constraint, int childrenLookupMaxRetries){ + this.children = childrenMustHave; + this.retriever = childrenRetriever; + this.constraint = constraint; + this.childrenLookupMaxRetries = childrenLookupMaxRetries; + } + } + + public RetryEngine(String title, int minutesToWait, Consumer logger) { + this(title, minutesToWait, null, logger); + } + public RetryEngine(String title, int minutesToWait, ChildrenRequirements childrenRequirements, Consumer logger) { + this.title = title; + this.minutesToWait = minutesToWait; + this.childrenRequirements = childrenRequirements; + this.logger = logger; + } + + public D tryUntilGotDesired(Supplier tryToGet, final int tooMuchTriesThreshold) throws TooMuchTriesException { + AtomicInteger loopCount = new AtomicInteger(1); + D desired = null; + boolean waitForChildren = Optional.ofNullable(childrenRequirements).map(req -> req.children > 0).orElse(false); + while (Objects.isNull(desired)) { + try { + desired = tryToGet.get(); + } catch (Exception e) { + log("An error was occurred when trying to get element but it only will count as a failed try. The stacktrace will be printed."); + e.printStackTrace(); + } + if (Objects.isNull(desired)) { + if (loopCount.get() >= tooMuchTriesThreshold) { + throw new TooMuchTriesException("Too much tries when retrieving desired element"); + } + if (loopCount.get() == 1) log(msg("The element was not found yet and will retry every {0} minutes - {1}", minutesToWait, getCurrentTime())); + loopCount.incrementAndGet(); + waitMinutes(minutesToWait); + } else if (waitForChildren) { + childrenCheckingLoop(desired); + } + } + log("the try was satisfied and will return the desired element/s"); + return desired; + } + + private void childrenCheckingLoop(D got) { + AtomicInteger loopCount = new AtomicInteger(1); + boolean waitForChildren=true; + boolean childrenConstraintSatisfied = childrenRequirements.constraint == null; + while (waitForChildren) { + List children = childrenRequirements.retriever.apply(got); + if (children.size() < childrenRequirements.children) { + if (loopCount.get() >= childrenRequirements.childrenLookupMaxRetries) { + log(msg("Too much tries when retrieving children from {0} while current is {1} and expected {2}. However, we will work with the files we have.", + got.getClass().getSimpleName(), children.size(), childrenRequirements.children)); + waitForChildren = false; + } + if (loopCount.get() == 1) + log(msg("Not enough children yet ({2} vs {3}) and will retry in {0} minutes - {1}", + minutesToWait, getCurrentTime(), children.size(), childrenRequirements.children)); + loopCount.incrementAndGet(); + waitMinutes(minutesToWait); + } else { + if (!childrenConstraintSatisfied) { + childrenConstraintSatisfied = children.stream().allMatch(childrenRequirements.constraint::apply); + } + else { + waitForChildren = false; + waitSeconds(50); + } + } + } + } + + private void log (String msg) { + logger.accept(msg("-|*|RetryEngine.{0}|*|- {1}", title, msg)); + } + +}