Rewrite of recording related model actions
This commit is contained in:
parent
e5468f6849
commit
f216b8240b
|
@ -0,0 +1,56 @@
|
|||
package ctbrec.ui.action;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import ctbrec.ui.tasks.TaskExecutionException;
|
||||
import javafx.application.Platform;
|
||||
|
||||
public abstract class AbstractAction<P, R> {
|
||||
|
||||
private R result;
|
||||
|
||||
public CompletableFuture<Optional<R>> execute(P param) {
|
||||
try {
|
||||
result = doExecute(param);
|
||||
Platform.runLater(() -> onSuccess(Optional.ofNullable(result)));
|
||||
return CompletableFuture.completedFuture(Optional.of(result));
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> onError(e));
|
||||
return CompletableFuture.failedFuture(e);
|
||||
} finally {
|
||||
Platform.runLater(() -> done(Optional.ofNullable(result)));
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract R doExecute(P param) throws InvalidKeyException, NoSuchAlgorithmException, IOException;
|
||||
|
||||
public CompletableFuture<Optional<R>> executeAsync(P param) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
result = doExecute(param);
|
||||
Platform.runLater(() -> onSuccess(Optional.ofNullable(result)));
|
||||
return Optional.of(result);
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> onError(e));
|
||||
throw new TaskExecutionException(e);
|
||||
} finally {
|
||||
Platform.runLater(() -> done(Optional.ofNullable(result)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends AbstractAction<P, R>> T beforeOnGuiThread(Runnable r) {
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
protected void onSuccess(Optional<R> result) {}
|
||||
|
||||
protected void onError(Exception e) {}
|
||||
|
||||
protected void done(Optional<R> result) {}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package ctbrec.ui.action;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import ctbrec.ui.tasks.AbstractModelTask;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Cursor;
|
||||
import javafx.scene.Node;
|
||||
|
||||
public abstract class AbstractModelAction {
|
||||
|
||||
protected Node source;
|
||||
protected List<? extends Model> models;
|
||||
protected Recorder recorder;
|
||||
private AbstractModelTask task;
|
||||
|
||||
protected AbstractModelAction(Node source, List<? extends Model> models, Recorder recorder, AbstractModelTask task) {
|
||||
this.source = source;
|
||||
this.models = models;
|
||||
this.recorder = recorder;
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
protected CompletableFuture<List<Result>> execute(String errorHeader, String errorMsg) {
|
||||
source.setCursor(Cursor.WAIT);
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
final List<Result> result = new ArrayList<>(models.size());
|
||||
final List<CompletableFuture<Model>> futures = new ArrayList<>(models.size());
|
||||
for (Model model : models) {
|
||||
futures.add(task
|
||||
.executeSync(model)
|
||||
.whenComplete((mdl, ex) ->
|
||||
result.add(new Result(model, ex))));
|
||||
}
|
||||
Platform.runLater(() -> source.setCursor(Cursor.DEFAULT));
|
||||
List<Result> failed = result.stream().filter(Result::failed).collect(Collectors.toList());
|
||||
if (!failed.isEmpty()) {
|
||||
Throwable t = failed.get(0).getThrowable();
|
||||
String failedModelList = failed.stream().map(Result::getModel).map(Model::getDisplayName).collect(Collectors.joining(", "));
|
||||
String msg = MessageFormat.format(errorMsg, failedModelList);
|
||||
Dialogs.showError(source.getScene(), errorHeader, msg, t);
|
||||
}
|
||||
return result;
|
||||
}, GlobalThreadPool.get());
|
||||
}
|
||||
|
||||
public static class Result {
|
||||
private Model model;
|
||||
private Throwable throwable;
|
||||
|
||||
public Result(Model model, Throwable t) {
|
||||
this.model = model;
|
||||
this.throwable = t;
|
||||
}
|
||||
|
||||
public boolean successful() {
|
||||
return throwable == null;
|
||||
}
|
||||
|
||||
public boolean failed() {
|
||||
return throwable != null;
|
||||
}
|
||||
|
||||
public Model getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public Throwable getThrowable() {
|
||||
return throwable;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,30 +1,20 @@
|
|||
package ctbrec.ui.action;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import ctbrec.Model;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import javafx.application.Platform;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.ui.tasks.FollowTask;
|
||||
import javafx.scene.Node;
|
||||
|
||||
public class FollowAction extends ModelMassEditAction {
|
||||
public class FollowAction extends AbstractModelAction {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FollowAction.class);
|
||||
public FollowAction(Node source, List<? extends Model> models, Recorder recorder) {
|
||||
super(source, models, recorder, new FollowTask(recorder));
|
||||
}
|
||||
|
||||
public FollowAction(Node source, List<? extends Model> models) {
|
||||
super(source, models);
|
||||
action = m -> {
|
||||
try {
|
||||
m.getSite().login();
|
||||
m.follow();
|
||||
} catch(Exception e) {
|
||||
LOG.error("Couldn't follow model {}", m, e);
|
||||
Platform.runLater(() ->
|
||||
Dialogs.showError(source.getScene(), "Couldn't follow model", "Following " + m.getName() + " failed: " + e.getMessage(), e));
|
||||
}
|
||||
};
|
||||
public CompletableFuture<List<Result>> execute() {
|
||||
return super.execute("Couldn't follow model", "Following of {0} failed:");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import ctbrec.Config;
|
|||
import ctbrec.Model;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.ui.JavaFxModel;
|
||||
import ctbrec.ui.action.AbstractModelAction.Result;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import javafx.scene.Node;
|
||||
|
||||
|
@ -44,7 +45,8 @@ public class IgnoreModelsAction {
|
|||
if (withRemoveDialog) {
|
||||
boolean removeAsWell = Dialogs.showConfirmDialog("Ignore Model", null, "Remove as well?", source.getScene());
|
||||
if (removeAsWell) {
|
||||
new StopRecordingAction(source, selectedModels, recorder).execute(callback);
|
||||
new StopRecordingAction(source, selectedModels, recorder).execute()
|
||||
.whenComplete((r, ex) -> r.stream().map(Result::getModel).forEach(callback::accept));
|
||||
}
|
||||
} else {
|
||||
for (Model model : selectedModels) {
|
||||
|
|
|
@ -15,9 +15,9 @@ public class MarkForLaterRecordingAction extends ModelMassEditAction {
|
|||
action = m -> {
|
||||
try {
|
||||
recorder.markForLaterRecording(m, recordLater);
|
||||
} catch(Exception e) {
|
||||
Platform.runLater(() ->
|
||||
Dialogs.showError(source.getScene(), "Couldn't resume recording of model", "Resuming recording of " + m.getName() + " failed", e));
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> Dialogs.showError(source.getScene(), "Couldn't model mark model for later recording",
|
||||
"Marking for later recording of " + m.getName() + " failed", e));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -43,33 +43,35 @@ public class ModelMassEditAction {
|
|||
execute(m -> {});
|
||||
}
|
||||
|
||||
public void executeSync(Consumer<Model> callback) {
|
||||
Platform.runLater(() -> source.setCursor(Cursor.WAIT));
|
||||
Consumer<Model> cb = Objects.requireNonNull(callback, "Callback is null, call execute() instead");
|
||||
List<Future<?>> futures = new LinkedList<>();
|
||||
for (Model model : getModels()) {
|
||||
futures.add(GlobalThreadPool.submit(() -> {
|
||||
action.accept(model);
|
||||
cb.accept(model);
|
||||
}));
|
||||
}
|
||||
Exception ex = null;
|
||||
for (Future<?> future : futures) {
|
||||
try {
|
||||
future.get();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (ExecutionException e) {
|
||||
ex = e;
|
||||
}
|
||||
}
|
||||
if (ex != null) {
|
||||
LOG.error("Error while executing model mass edit", ex);
|
||||
Dialogs.showError(source.getScene(), "Error", "Error while execution action", ex);
|
||||
}
|
||||
Platform.runLater(() -> source.setCursor(Cursor.DEFAULT));
|
||||
}
|
||||
|
||||
public void execute(Consumer<Model> callback) {
|
||||
GlobalThreadPool.submit(() -> {
|
||||
Platform.runLater(() -> source.setCursor(Cursor.WAIT));
|
||||
Consumer<Model> cb = Objects.requireNonNull(callback, "Callback is null, call execute() instead");
|
||||
List<Future<?>> futures = new LinkedList<>();
|
||||
for (Model model : getModels()) {
|
||||
futures.add(GlobalThreadPool.submit(() -> {
|
||||
action.accept(model);
|
||||
cb.accept(model);
|
||||
}));
|
||||
}
|
||||
Exception ex = null;
|
||||
for (Future<?> future : futures) {
|
||||
try {
|
||||
future.get();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (ExecutionException e) {
|
||||
ex = e;
|
||||
}
|
||||
}
|
||||
if (ex != null) {
|
||||
LOG.error("Error while executing model mass edit", ex);
|
||||
Dialogs.showError(source.getScene(), "Error", "Error while execution action", ex);
|
||||
}
|
||||
Platform.runLater(() -> source.setCursor(Cursor.DEFAULT));
|
||||
});
|
||||
GlobalThreadPool.submit(() -> executeSync(callback));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
|
@ -1,24 +1,20 @@
|
|||
package ctbrec.ui.action;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import ctbrec.Model;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import javafx.application.Platform;
|
||||
import ctbrec.ui.tasks.PauseRecordingTask;
|
||||
import javafx.scene.Node;
|
||||
|
||||
public class PauseAction extends ModelMassEditAction {
|
||||
public class PauseAction extends AbstractModelAction {
|
||||
|
||||
public PauseAction(Node source, List<? extends Model> models, Recorder recorder) {
|
||||
super(source, models);
|
||||
action = m -> {
|
||||
try {
|
||||
recorder.suspendRecording(m);
|
||||
} catch(Exception e) {
|
||||
Platform.runLater(() ->
|
||||
Dialogs.showError(source.getScene(), "Couldn't suspend recording of model", "Suspending recording of " + m.getName() + " failed", e));
|
||||
}
|
||||
};
|
||||
public PauseAction(Node source, List<Model> models, Recorder recorder) {
|
||||
super(source, models, recorder, new PauseRecordingTask(recorder));
|
||||
}
|
||||
|
||||
public CompletableFuture<List<Result>> execute() {
|
||||
return super.execute("Couldn't pause recording", "Pausing recording of {0} failed:");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,20 @@
|
|||
package ctbrec.ui.action;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import ctbrec.Model;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import javafx.application.Platform;
|
||||
import ctbrec.ui.tasks.ResumeRecordingTask;
|
||||
import javafx.scene.Node;
|
||||
|
||||
public class ResumeAction extends ModelMassEditAction {
|
||||
public class ResumeAction extends AbstractModelAction {
|
||||
|
||||
public ResumeAction(Node source, List<? extends Model> models, Recorder recorder) {
|
||||
super(source, models);
|
||||
action = m -> {
|
||||
try {
|
||||
recorder.resumeRecording(m);
|
||||
} catch(Exception e) {
|
||||
Platform.runLater(() ->
|
||||
Dialogs.showError(source.getScene(), "Couldn't resume recording of model", "Resuming recording of " + m.getName() + " failed", e));
|
||||
}
|
||||
};
|
||||
public ResumeAction(Node source, List<Model> models, Recorder recorder) {
|
||||
super(source, models, recorder, new ResumeRecordingTask(recorder));
|
||||
}
|
||||
|
||||
public CompletableFuture<List<Result>> execute() {
|
||||
return super.execute("Couldn't resume recording", "Resuming recording of {0} failed:");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import java.security.NoSuchAlgorithmException;
|
|||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -20,6 +19,8 @@ import ctbrec.SubsequentAction;
|
|||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.ui.controls.DateTimePicker;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import ctbrec.ui.tasks.StartRecordingTask;
|
||||
import javafx.application.Platform;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.Cursor;
|
||||
import javafx.scene.Node;
|
||||
|
@ -83,7 +84,7 @@ public class SetStopDateAction {
|
|||
}
|
||||
return true;
|
||||
}, GlobalThreadPool.get()).whenComplete((r, e) -> {
|
||||
source.setCursor(Cursor.DEFAULT);
|
||||
Platform.runLater(() -> source.setCursor(Cursor.DEFAULT));
|
||||
if (e != null) {
|
||||
LOG.error("Error", e);
|
||||
}
|
||||
|
@ -97,13 +98,17 @@ public class SetStopDateAction {
|
|||
model.setRecordUntil(stopAt);
|
||||
model.setRecordUntilSubsequentAction(action);
|
||||
try {
|
||||
if (!recorder.isTracked(model)) {
|
||||
new StartRecordingAction(source, List.of(model), recorder).execute(m -> {
|
||||
if (!recorder.isTracked(model) || model.isMarkedForLaterRecording()) {
|
||||
new StartRecordingTask(recorder).executeSync(model)
|
||||
.thenAccept(m -> {
|
||||
try {
|
||||
recorder.stopRecordingAt(m);
|
||||
} catch (InvalidKeyException | NoSuchAlgorithmException | IOException e1) {
|
||||
showError(e1);
|
||||
}
|
||||
}).exceptionally(ex -> {
|
||||
showError(ex);
|
||||
return null;
|
||||
});
|
||||
} else {
|
||||
recorder.stopRecordingAt(model);
|
||||
|
@ -113,8 +118,8 @@ public class SetStopDateAction {
|
|||
}
|
||||
}
|
||||
|
||||
private void showError(Exception e) {
|
||||
Dialogs.showError(source.getScene(), "Error", "Couln't set stop date", e);
|
||||
private void showError(Throwable t) {
|
||||
Platform.runLater(() -> Dialogs.showError(source.getScene(), "Error", "Couln't set stop date", t));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,24 +1,20 @@
|
|||
package ctbrec.ui.action;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import ctbrec.Model;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import javafx.application.Platform;
|
||||
import ctbrec.ui.tasks.StartRecordingTask;
|
||||
import javafx.scene.Node;
|
||||
|
||||
public class StartRecordingAction extends ModelMassEditAction {
|
||||
public class StartRecordingAction extends AbstractModelAction {
|
||||
|
||||
public StartRecordingAction(Node source, List<? extends Model> models, Recorder recorder) {
|
||||
super(source, models);
|
||||
action = m -> {
|
||||
try {
|
||||
recorder.addModel(m);
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() ->
|
||||
Dialogs.showError(source.getScene(), "Couldn't start recording", "Starting recording of " + m.getName() + " failed", e));
|
||||
}
|
||||
};
|
||||
public StartRecordingAction(Node source, List<Model> models, Recorder recorder) {
|
||||
super(source, models, recorder, new StartRecordingTask(recorder));
|
||||
}
|
||||
|
||||
public CompletableFuture<List<Result>> execute() {
|
||||
return super.execute("Couldn't start recording", "Starting recording of {0} failed:");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,20 @@
|
|||
package ctbrec.ui.action;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import ctbrec.Model;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import javafx.application.Platform;
|
||||
import ctbrec.ui.tasks.StopRecordingTask;
|
||||
import javafx.scene.Node;
|
||||
|
||||
public class StopRecordingAction extends ModelMassEditAction {
|
||||
public class StopRecordingAction extends AbstractModelAction {
|
||||
|
||||
public StopRecordingAction(Node source, List<? extends Model> models, Recorder recorder) {
|
||||
super(source, models);
|
||||
action = m -> {
|
||||
try {
|
||||
recorder.stopRecording(m);
|
||||
} catch(Exception e) {
|
||||
Platform.runLater(() ->
|
||||
Dialogs.showError(source.getScene(), "Couldn't stop recording", "Stopping recording of " + m.getName() + " failed", e));
|
||||
}
|
||||
};
|
||||
super(source, models, recorder, new StopRecordingTask(recorder));
|
||||
}
|
||||
|
||||
public CompletableFuture<List<Result>> execute() {
|
||||
return super.execute("Couldn't stop recording", "Stopping recording of {0} failed:");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package ctbrec.ui.action;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import ctbrec.Model;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.ui.tasks.UnfollowTask;
|
||||
import javafx.scene.Node;
|
||||
|
||||
public class UnfollowAction extends AbstractModelAction {
|
||||
|
||||
public UnfollowAction(Node source, List<? extends Model> models, Recorder recorder) {
|
||||
super(source, models, recorder, new UnfollowTask(recorder));
|
||||
}
|
||||
|
||||
public CompletableFuture<List<Result>> execute() {
|
||||
return super.execute("Couldn't unfollow model", "Unfollowing of {0} failed:");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package ctbrec.ui.menu;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ctbrec.Model;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.ui.action.AbstractModelAction.Result;
|
||||
import ctbrec.ui.action.FollowAction;
|
||||
import ctbrec.ui.action.TriConsumer;
|
||||
import ctbrec.ui.action.UnfollowAction;
|
||||
import javafx.scene.Node;
|
||||
|
||||
public class FollowUnfollowHandler {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FollowUnfollowHandler.class);
|
||||
|
||||
private Node source;
|
||||
private Recorder recorder;
|
||||
private TriConsumer<Model, Boolean, Boolean> callback;
|
||||
|
||||
public FollowUnfollowHandler(Node source, Recorder recorder, TriConsumer<Model, Boolean, Boolean> callback) {
|
||||
this.source = source;
|
||||
this.recorder = recorder;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
protected void follow(List<Model> selectedModels) {
|
||||
new FollowAction(source, selectedModels, recorder).execute().thenAccept(r -> {
|
||||
r.stream().filter(rs -> rs.getThrowable() == null).map(Result::getModel).forEach(m -> callback.accept(m, true, true));
|
||||
r.stream().filter(rs -> rs.getThrowable() != null).map(Result::getModel).forEach(m -> callback.accept(m, true, false));
|
||||
}).exceptionally(ex -> {
|
||||
LOG.error("Couldn't follow model", ex);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
protected void unfollow(List<Model> selectedModels) {
|
||||
new UnfollowAction(source, selectedModels, recorder).execute().thenAccept(r -> {
|
||||
r.stream().filter(rs -> rs.getThrowable() == null).map(Result::getModel).forEach(m -> callback.accept(m, false, true));
|
||||
r.stream().filter(rs -> rs.getThrowable() != null).map(Result::getModel).forEach(m -> callback.accept(m, false, false));
|
||||
}).exceptionally(ex -> {
|
||||
LOG.error("Couldn't unfollow model", ex);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@ import java.security.InvalidKeyException;
|
|||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
@ -13,23 +12,20 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ctbrec.Config;
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.ModelGroup;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.ui.AutosizeAlert;
|
||||
import ctbrec.ui.DesktopIntegration;
|
||||
import ctbrec.ui.SiteUiFactory;
|
||||
import ctbrec.ui.StreamSourceSelectionDialog;
|
||||
import ctbrec.ui.action.AbstractModelAction.Result;
|
||||
import ctbrec.ui.action.AddToGroupAction;
|
||||
import ctbrec.ui.action.EditNotesAction;
|
||||
import ctbrec.ui.action.IgnoreModelsAction;
|
||||
import ctbrec.ui.action.MarkForLaterRecordingAction;
|
||||
import ctbrec.ui.action.OpenRecordingsDir;
|
||||
import ctbrec.ui.action.PauseAction;
|
||||
import ctbrec.ui.action.PlayAction;
|
||||
import ctbrec.ui.action.RemoveTimeLimitAction;
|
||||
import ctbrec.ui.action.ResumeAction;
|
||||
import ctbrec.ui.action.SetPortraitAction;
|
||||
import ctbrec.ui.action.SetStopDateAction;
|
||||
import ctbrec.ui.action.StartRecordingAction;
|
||||
|
@ -38,8 +34,6 @@ import ctbrec.ui.action.TipAction;
|
|||
import ctbrec.ui.action.TriConsumer;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import ctbrec.ui.tabs.FollowedTab;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Cursor;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
|
@ -214,9 +208,9 @@ public class ModelMenuContributor {
|
|||
var site = selectedModels.get(0).getSite();
|
||||
if (site.supportsFollow()) {
|
||||
var follow = new MenuItem("Follow");
|
||||
follow.setOnAction(e -> follow(selectedModels, true));
|
||||
follow.setOnAction(e -> new FollowUnfollowHandler(source, recorder, followCallback).follow(selectedModels));
|
||||
var unfollow = new MenuItem("Unfollow");
|
||||
unfollow.setOnAction(e -> follow(selectedModels, false));
|
||||
unfollow.setOnAction(e -> new FollowUnfollowHandler(source, recorder, followCallback).unfollow(selectedModels));
|
||||
|
||||
var followOrUnFollow = isFollowedTab() ? unfollow : follow;
|
||||
followOrUnFollow.setDisable(!site.credentialsAvailable());
|
||||
|
@ -233,52 +227,6 @@ public class ModelMenuContributor {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected void follow(List<Model> selectedModels, boolean follow) {
|
||||
for (Model model : selectedModels) {
|
||||
follow(model, follow);
|
||||
}
|
||||
}
|
||||
|
||||
CompletableFuture<Boolean> follow(Model model, boolean follow) {
|
||||
source.setCursor(Cursor.WAIT);
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
var success = true;
|
||||
try {
|
||||
if (follow) {
|
||||
SiteUiFactory.getUi(model.getSite()).login();
|
||||
boolean followed = model.follow();
|
||||
if (followed) {
|
||||
success = true;
|
||||
} else {
|
||||
Dialogs.showError(source.getScene(), "Couldn't follow model", "", null);
|
||||
success = false;
|
||||
}
|
||||
} else {
|
||||
SiteUiFactory.getUi(model.getSite()).login();
|
||||
boolean unfollowed = model.unfollow();
|
||||
if (unfollowed) {
|
||||
success = true;
|
||||
} else {
|
||||
Dialogs.showError(source.getScene(), "Couldn't unfollow model", "", null);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
} catch (Exception e1) {
|
||||
LOG.error("Couldn't follow/unfollow model {}", model.getName(), e1);
|
||||
String msg = "I/O error while following/unfollowing model " + model.getName() + ": ";
|
||||
Dialogs.showError(source.getScene(), "Couldn't follow/unfollow model", msg, e1);
|
||||
return false;
|
||||
} finally {
|
||||
final boolean result = success;
|
||||
Platform.runLater(() -> {
|
||||
source.setCursor(Cursor.DEFAULT);
|
||||
followCallback.accept(model, follow, result);
|
||||
});
|
||||
}
|
||||
}, GlobalThreadPool.get());
|
||||
}
|
||||
|
||||
private void addSwitchStreamSource(ContextMenu menu, List<Model> selectedModels) {
|
||||
var model = selectedModels.get(0);
|
||||
if (!recorder.isTracked(model)) {
|
||||
|
@ -352,9 +300,9 @@ public class ModelMenuContributor {
|
|||
var first = selectedModels.get(0);
|
||||
if (recorder.isTracked(first)) {
|
||||
var pause = new MenuItem("Pause Recording");
|
||||
pause.setOnAction(e -> new PauseAction(source, selectedModels, recorder).execute(m -> executeCallback()));
|
||||
pause.setOnAction(e -> new PauseResumeHandler(source, recorder, callback).pause(selectedModels));
|
||||
var resume = new MenuItem("Resume Recording");
|
||||
resume.setOnAction(e -> new ResumeAction(source, selectedModels, recorder).execute(m -> executeCallback()));
|
||||
resume.setOnAction(e -> new PauseResumeHandler(source, recorder, callback).resume(selectedModels));
|
||||
var pauseResume = recorder.isSuspended(first) ? resume : pause;
|
||||
menu.getItems().add(pauseResume);
|
||||
}
|
||||
|
@ -399,10 +347,6 @@ public class ModelMenuContributor {
|
|||
var start = new MenuItem(text);
|
||||
menu.getItems().add(start);
|
||||
start.setOnAction(e -> {
|
||||
selectedModels.forEach(m -> {
|
||||
m.setMarkedForLaterRecording(false);
|
||||
m.setSuspended(false);
|
||||
});
|
||||
selectedModels.forEach(m -> new SetStopDateAction(source, m, recorder).execute() //
|
||||
.thenAccept(b -> executeCallback()));
|
||||
});
|
||||
|
@ -473,11 +417,23 @@ public class ModelMenuContributor {
|
|||
}
|
||||
|
||||
private void startRecording(List<Model> models) {
|
||||
new StartRecordingAction(source, models, recorder).execute(startStopCallback);
|
||||
new StartRecordingAction(source, models, recorder).execute()
|
||||
.whenComplete((r, ex) -> {
|
||||
if (ex != null) {
|
||||
LOG.error("Error while starting recordings", ex);
|
||||
}
|
||||
r.stream().map(Result::getModel).forEach(startStopCallback);
|
||||
});
|
||||
}
|
||||
|
||||
private void stopRecording(List<Model> models) {
|
||||
new StopRecordingAction(source, models, recorder).execute(startStopCallback);
|
||||
new StopRecordingAction(source, models, recorder).execute()
|
||||
.whenComplete((r, ex) -> {
|
||||
if (ex != null) {
|
||||
LOG.error("Error while stopping recordings", ex);
|
||||
}
|
||||
r.stream().map(Result::getModel).forEach(startStopCallback);
|
||||
});
|
||||
}
|
||||
|
||||
private void executeCallback() {
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package ctbrec.ui.menu;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ctbrec.Model;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.ui.action.PauseAction;
|
||||
import ctbrec.ui.action.ResumeAction;
|
||||
import javafx.scene.Node;
|
||||
|
||||
public class PauseResumeHandler {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PauseResumeHandler.class);
|
||||
|
||||
private Node source;
|
||||
private Recorder recorder;
|
||||
private Runnable callback;
|
||||
|
||||
public PauseResumeHandler(Node source, Recorder recorder, Runnable callback) {
|
||||
this.source = source;
|
||||
this.recorder = recorder;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
protected void pause(List<Model> selectedModels) {
|
||||
new PauseAction(source, selectedModels, recorder).execute()
|
||||
.exceptionally(ex -> {
|
||||
LOG.error("Error while pausing recordings", ex);
|
||||
return null;
|
||||
}).whenComplete((r, ex) -> executeCallback());
|
||||
}
|
||||
|
||||
protected void resume(List<Model> selectedModels) {
|
||||
new ResumeAction(source, selectedModels, recorder).execute()
|
||||
.exceptionally(ex -> {
|
||||
LOG.error("Error while resuming recordings", ex);
|
||||
return null;
|
||||
}).whenComplete((r, ex) -> executeCallback());
|
||||
}
|
||||
|
||||
private void executeCallback() {
|
||||
try {
|
||||
callback.run();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error while executing menu callback", e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -476,10 +476,15 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
|||
})
|
||||
.withFollowCallback( (mdl, fllw, success) -> {
|
||||
if (Boolean.TRUE.equals(fllw) && Boolean.TRUE.equals(success)) {
|
||||
getThumbCell(mdl).ifPresent(this::showAddToFollowedAnimation);
|
||||
Platform.runLater(() -> getThumbCell(mdl).ifPresent(this::showAddToFollowedAnimation));
|
||||
}
|
||||
if (Boolean.FALSE.equals(fllw)) {
|
||||
selectedThumbCells.clear();
|
||||
Platform.runLater(() -> {
|
||||
if (this instanceof FollowedTab) {
|
||||
getThumbCell(mdl).ifPresent(thumbCell -> grid.getChildren().remove(thumbCell));
|
||||
}
|
||||
selectedThumbCells.clear();
|
||||
});
|
||||
}
|
||||
})
|
||||
.withIgnoreCallback(m -> getThumbCell(m).ifPresent(thumbCell -> {
|
||||
|
|
|
@ -18,6 +18,7 @@ import ctbrec.Model;
|
|||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.sites.Site;
|
||||
import ctbrec.ui.JavaFxModel;
|
||||
import ctbrec.ui.action.AbstractModelAction.Result;
|
||||
import ctbrec.ui.action.CheckModelAccountAction;
|
||||
import ctbrec.ui.action.StopRecordingAction;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
|
@ -61,8 +62,8 @@ public class RecordLaterTab extends AbstractRecordedModelsTab implements TabSele
|
|||
root.setCenter(scrollPane);
|
||||
setContent(root);
|
||||
|
||||
checkModelAccountExistance.setOnAction(evt -> new CheckModelAccountAction(checkModelAccountExistance, recorder)
|
||||
.execute(Model::isMarkedForLaterRecording));
|
||||
checkModelAccountExistance
|
||||
.setOnAction(evt -> new CheckModelAccountAction(checkModelAccountExistance, recorder).execute(Model::isMarkedForLaterRecording));
|
||||
|
||||
restoreState();
|
||||
}
|
||||
|
@ -166,10 +167,12 @@ public class RecordLaterTab extends AbstractRecordedModelsTab implements TabSele
|
|||
}
|
||||
if (confirmed) {
|
||||
List<Model> models = selectedModels.stream().map(JavaFxModel::getDelegate).collect(Collectors.toList());
|
||||
new StopRecordingAction(getTabPane(), models, recorder).execute(m -> Platform.runLater(() -> {
|
||||
table.getSelectionModel().clearSelection(table.getItems().indexOf(m));
|
||||
table.getItems().remove(m);
|
||||
}));
|
||||
new StopRecordingAction(getTabPane(), models, recorder).execute().whenComplete((r, ex) -> {
|
||||
r.stream().map(Result::getModel).forEach(m -> Platform.runLater(() -> {
|
||||
table.getSelectionModel().clearSelection(table.getItems().indexOf(m));
|
||||
table.getItems().remove(m);
|
||||
}));
|
||||
});
|
||||
portraitCache.invalidateAll(models);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import ctbrec.Recording;
|
|||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.sites.Site;
|
||||
import ctbrec.ui.JavaFxModel;
|
||||
import ctbrec.ui.action.AbstractModelAction.Result;
|
||||
import ctbrec.ui.action.CheckModelAccountAction;
|
||||
import ctbrec.ui.action.PauseAction;
|
||||
import ctbrec.ui.action.ResumeAction;
|
||||
|
@ -358,10 +359,12 @@ public class RecordedModelsTab extends AbstractRecordedModelsTab implements TabS
|
|||
}
|
||||
if (confirmed) {
|
||||
List<Model> models = selectedModels.stream().map(JavaFxModel::getDelegate).collect(Collectors.toList());
|
||||
new StopRecordingAction(getTabPane(), models, recorder).execute(m -> Platform.runLater(() -> {
|
||||
table.getSelectionModel().clearSelection(table.getItems().indexOf(m));
|
||||
table.getItems().remove(m);
|
||||
}));
|
||||
new StopRecordingAction(getTabPane(), models, recorder).execute().whenComplete((r, ex) -> {
|
||||
r.stream().map(Result::getModel).forEach(m -> Platform.runLater(() -> {
|
||||
table.getSelectionModel().clearSelection(table.getItems().indexOf(m));
|
||||
table.getItems().remove(m);
|
||||
}));
|
||||
});
|
||||
portraitCache.invalidateAll(models);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package ctbrec.ui.tasks;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.recorder.Recorder;
|
||||
|
||||
public abstract class AbstractModelTask {
|
||||
protected Recorder recorder;
|
||||
private Consumer<Model> concreteTask;
|
||||
|
||||
protected AbstractModelTask(Recorder recorder, Consumer<Model> concreteTask) {
|
||||
this.recorder = recorder;
|
||||
this.concreteTask = concreteTask;
|
||||
}
|
||||
|
||||
public CompletableFuture<Model> executeSync(Model model) {
|
||||
try {
|
||||
concreteTask.accept(model);
|
||||
return CompletableFuture.completedFuture(model);
|
||||
} catch (Exception e) {
|
||||
return CompletableFuture.failedFuture(e);
|
||||
}
|
||||
}
|
||||
|
||||
public CompletableFuture<Model> execute(Model model) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
concreteTask.accept(model);
|
||||
return model;
|
||||
} catch (Exception e) {
|
||||
throw new TaskExecutionException(e);
|
||||
}
|
||||
}, GlobalThreadPool.get());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package ctbrec.ui.tasks;
|
||||
|
||||
import ctbrec.recorder.Recorder;
|
||||
|
||||
public class FollowTask extends AbstractModelTask {
|
||||
|
||||
public FollowTask(Recorder recorder) {
|
||||
super(recorder, model -> {
|
||||
try {
|
||||
if (model.getSite().login()) {
|
||||
if (!model.follow()) {
|
||||
throw new TaskExecutionException(new RuntimeException("Following " + model.getSite().getName() + " failed"));
|
||||
}
|
||||
} else {
|
||||
throw new TaskExecutionException(new RuntimeException("Login to " + model.getSite().getName() + " failed"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new TaskExecutionException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package ctbrec.ui.tasks;
|
||||
|
||||
import ctbrec.recorder.Recorder;
|
||||
|
||||
public class PauseRecordingTask extends AbstractModelTask {
|
||||
|
||||
public PauseRecordingTask(Recorder recorder) {
|
||||
super(recorder, model -> {
|
||||
try {
|
||||
model.setSuspended(true);
|
||||
recorder.suspendRecording(model);
|
||||
} catch (Exception e) {
|
||||
throw new TaskExecutionException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package ctbrec.ui.tasks;
|
||||
|
||||
import ctbrec.recorder.Recorder;
|
||||
|
||||
public class ResumeRecordingTask extends AbstractModelTask {
|
||||
|
||||
public ResumeRecordingTask(Recorder recorder) {
|
||||
super(recorder, model -> {
|
||||
try {
|
||||
model.setSuspended(false);
|
||||
recorder.resumeRecording(model);
|
||||
} catch (Exception e) {
|
||||
throw new TaskExecutionException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package ctbrec.ui.tasks;
|
||||
|
||||
import ctbrec.recorder.Recorder;
|
||||
|
||||
public class StartRecordingTask extends AbstractModelTask {
|
||||
|
||||
public StartRecordingTask(Recorder recorder) {
|
||||
super(recorder, model -> {
|
||||
try {
|
||||
model.setMarkedForLaterRecording(false);
|
||||
recorder.addModel(model);
|
||||
} catch (Exception e) {
|
||||
throw new TaskExecutionException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package ctbrec.ui.tasks;
|
||||
|
||||
import ctbrec.recorder.Recorder;
|
||||
|
||||
public class StopRecordingTask extends AbstractModelTask {
|
||||
|
||||
public StopRecordingTask(Recorder recorder) {
|
||||
super(recorder, model -> {
|
||||
try {
|
||||
recorder.stopRecording(model);
|
||||
} catch (Exception e) {
|
||||
throw new TaskExecutionException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package ctbrec.ui.tasks;
|
||||
|
||||
public class TaskExecutionException extends RuntimeException {
|
||||
|
||||
public TaskExecutionException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package ctbrec.ui.tasks;
|
||||
|
||||
import ctbrec.recorder.Recorder;
|
||||
|
||||
public class UnfollowTask extends AbstractModelTask {
|
||||
|
||||
public UnfollowTask(Recorder recorder) {
|
||||
super(recorder, model -> {
|
||||
try {
|
||||
if (model.getSite().login()) {
|
||||
if (!model.unfollow()) {
|
||||
throw new TaskExecutionException(new RuntimeException("Unfollowing " + model.getSite().getName() + " failed"));
|
||||
}
|
||||
} else {
|
||||
throw new TaskExecutionException(new RuntimeException("Login to " + model.getSite().getName() + " failed"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new TaskExecutionException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package ctbrec.ui.tasks;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import ctbrec.Model;
|
||||
import ctbrec.recorder.Recorder;
|
||||
|
||||
class StartRecordingTaskTest {
|
||||
|
||||
private Recorder recorder;
|
||||
private Model model;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
recorder = mock(Recorder.class);
|
||||
model = mock(Model.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecuteSyncHappyPath() {
|
||||
CompletableFuture<Model> future = new StartRecordingTask(recorder).executeSync(model);
|
||||
try {
|
||||
assertEquals(future.get(), model);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
fail("happy path should not throw an " + e.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecuteSyncWithException() throws InvalidKeyException, NoSuchAlgorithmException, IOException {
|
||||
String exMsg = "recorder not available";
|
||||
doThrow(new IOException(exMsg)).when(recorder).addModel(model);
|
||||
CompletableFuture<Model> future = new StartRecordingTask(recorder).executeSync(model);
|
||||
ExecutionException ex = assertThrows(ExecutionException.class, future::get);
|
||||
assertTrue(getRootCause(ex) instanceof IOException);
|
||||
assertEquals(exMsg, getRootCause(ex).getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecuteHappyPath() {
|
||||
CompletableFuture<Model> future = new StartRecordingTask(recorder).execute(model);
|
||||
try {
|
||||
assertEquals(future.get(), model);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
fail("happy path should not throw an " + e.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecuteWithException() throws InvalidKeyException, NoSuchAlgorithmException, IOException {
|
||||
String exMsg = "recorder not available";
|
||||
doThrow(new IOException(exMsg)).when(recorder).addModel(model);
|
||||
CompletableFuture<Model> future = new StartRecordingTask(recorder).execute(model);
|
||||
ExecutionException ex = assertThrows(ExecutionException.class, future::get);
|
||||
assertTrue(ex.getCause() instanceof TaskExecutionException);
|
||||
assertTrue(getRootCause(ex) instanceof IOException);
|
||||
assertEquals(exMsg, getRootCause(ex).getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void markedForLaterShouldGetStarted() throws InvalidKeyException, NoSuchAlgorithmException, IOException {
|
||||
when(model.isMarkedForLaterRecording()).thenReturn(true);
|
||||
new StartRecordingTask(recorder).executeSync(model);
|
||||
verify(model).setMarkedForLaterRecording(false);
|
||||
verify(recorder).addModel(model);
|
||||
}
|
||||
|
||||
private Throwable getRootCause(Throwable t) {
|
||||
if (t.getCause() != null) {
|
||||
return getRootCause(t.getCause());
|
||||
} else {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -70,7 +70,7 @@ public class NextGenLocalRecorder implements Recorder {
|
|||
private volatile boolean recording = true;
|
||||
private ReentrantLock recorderLock = new ReentrantLock();
|
||||
private ReentrantLock modelGroupLock = new ReentrantLock();
|
||||
private RecorderHttpClient client = new RecorderHttpClient();
|
||||
private RecorderHttpClient client;
|
||||
private Map<Model, Recording> recordingProcesses = Collections.synchronizedMap(new HashMap<>());
|
||||
private RecordingManager recordingManager;
|
||||
private RecordingPreconditions preconditions;
|
||||
|
@ -90,6 +90,7 @@ public class NextGenLocalRecorder implements Recorder {
|
|||
|
||||
public NextGenLocalRecorder(Config config, List<Site> sites) throws IOException {
|
||||
this.config = config;
|
||||
client = new RecorderHttpClient(config);
|
||||
downloadPool = Executors.newScheduledThreadPool(5, createThreadFactory("Download", MAX_PRIORITY));
|
||||
threadPoolScaler = new ThreadPoolScaler((ThreadPoolExecutor) downloadPool, 5);
|
||||
recordingManager = new RecordingManager(config, sites);
|
||||
|
@ -265,15 +266,7 @@ public class NextGenLocalRecorder implements Recorder {
|
|||
@Override
|
||||
public void addModel(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException {
|
||||
Optional<Model> existing = findModel(model);
|
||||
if (existing.isPresent()) {
|
||||
existing.get().setSuspended(model.isSuspended());
|
||||
existing.get().setMarkedForLaterRecording(model.isMarkedForLaterRecording());
|
||||
if (model.isMarkedForLaterRecording() && getRecordingProcesses().containsKey(model)) {
|
||||
stopRecording(model);
|
||||
} else {
|
||||
startRecordingProcess(existing.get());
|
||||
}
|
||||
} else {
|
||||
if (!existing.isPresent()) {
|
||||
LOG.info("Model {} added", model);
|
||||
recorderLock.lock();
|
||||
try {
|
||||
|
@ -574,7 +567,7 @@ public class NextGenLocalRecorder implements Recorder {
|
|||
Optional<Model> existingModel = findModel(model);
|
||||
if (existingModel.isPresent()) {
|
||||
Model m = existingModel.get();
|
||||
LOG.debug("Mark. Model found: {}", m);
|
||||
LOG.debug("Mark for later: {}. Model found: {}", mark, m);
|
||||
m.setMarkedForLaterRecording(mark);
|
||||
if (mark && getCurrentlyRecording().contains(m)) {
|
||||
LOG.debug("Stopping recording of {}", m);
|
||||
|
@ -585,8 +578,8 @@ public class NextGenLocalRecorder implements Recorder {
|
|||
stopRecording(model);
|
||||
}
|
||||
} else {
|
||||
LOG.debug("Model {} not found to mark for later recording", model);
|
||||
if (mark) {
|
||||
LOG.debug("Model {} not found to mark for later recording", model);
|
||||
model.setMarkedForLaterRecording(true);
|
||||
addModel(model);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue