some improvements, including work directly with production jobs
This commit is contained in:
parent
e0e95047dc
commit
bb75899bb9
2
pom.xml
2
pom.xml
|
@ -6,7 +6,7 @@
|
|||
|
||||
<groupId>tv.mangrana</groupId>
|
||||
<artifactId>mangrana-commons</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<version>3.0</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public abstract class JobFile<E> {
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 boolean scanMovieByPath(String fullDestinationPath) {
|
||||
try {
|
||||
return scanByPath(getPlexMoviePath2Refresh(fullDestinationPath));
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
public void scanMovieByPath(String fullDestinationPath) {
|
||||
scanByPath(getPlexMoviePath2Refresh(fullDestinationPath));
|
||||
}
|
||||
|
||||
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) {
|
||||
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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<D> {
|
||||
|
||||
private final String title;
|
||||
private final int minutesToWait;
|
||||
private final ChildrenRequirements<D> childrenRequirements;
|
||||
private final Consumer<String> logger;
|
||||
|
||||
public static class ChildrenRequirements<D> {
|
||||
final int children;
|
||||
final Function<D, List<D>> retriever;
|
||||
final Function<D, Boolean> constraint;
|
||||
final int childrenLookupMaxRetries;
|
||||
|
||||
public ChildrenRequirements(int childrenMustHave, Function<D, List<D>> childrenRetriever, Function<D, Boolean> constraint, int childrenLookupMaxRetries){
|
||||
this.children = childrenMustHave;
|
||||
this.retriever = childrenRetriever;
|
||||
this.constraint = constraint;
|
||||
this.childrenLookupMaxRetries = childrenLookupMaxRetries;
|
||||
}
|
||||
}
|
||||
|
||||
public RetryEngine(String title, int minutesToWait, Consumer<String> logger) {
|
||||
this(title, minutesToWait, null, logger);
|
||||
}
|
||||
public RetryEngine(String title, int minutesToWait, ChildrenRequirements<D> childrenRequirements, Consumer<String> logger) {
|
||||
this.title = title;
|
||||
this.minutesToWait = minutesToWait;
|
||||
this.childrenRequirements = childrenRequirements;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public D tryUntilGotDesired(Supplier<D> 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<D> 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));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue