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));
+ }
+
+}