forked from j62/ctbrec
Use global thread pool instead of creating new threads
This commit is contained in:
parent
ec9c463f80
commit
967b5dec42
|
@ -28,11 +28,10 @@ public class ExternalBrowser implements AutoCloseable {
|
|||
private static final ExternalBrowser INSTANCE = new ExternalBrowser();
|
||||
private Lock lock = new ReentrantLock();
|
||||
|
||||
private Process p;
|
||||
private Consumer<String> messageListener;
|
||||
private InputStream in;
|
||||
private OutputStream out;
|
||||
private Socket socket;
|
||||
private Socket socket; // NOSONAR
|
||||
private Thread reader;
|
||||
private volatile boolean stopped = true;
|
||||
private volatile boolean browserReady = false;
|
||||
|
@ -53,10 +52,10 @@ public class ExternalBrowser implements AutoCloseable {
|
|||
|
||||
File configDir = new File(Config.getInstance().getConfigDir(), "ctbrec-minimal-browser");
|
||||
String[] cmdline = OS.getBrowserCommand(configDir.getCanonicalPath());
|
||||
p = new ProcessBuilder(cmdline).start();
|
||||
Process p = new ProcessBuilder(cmdline).start();
|
||||
if (LOG.isTraceEnabled()) {
|
||||
new Thread(new StreamRedirector(p.getInputStream(), System.out)).start();
|
||||
new Thread(new StreamRedirector(p.getErrorStream(), System.err)).start();
|
||||
new Thread(new StreamRedirector(p.getInputStream(), System.out)).start(); // NOSONAR
|
||||
new Thread(new StreamRedirector(p.getErrorStream(), System.err)).start(); // NOSONAR
|
||||
} else {
|
||||
new Thread(new StreamRedirector(p.getInputStream(), OutputStream.nullOutputStream())).start();
|
||||
new Thread(new StreamRedirector(p.getErrorStream(), OutputStream.nullOutputStream())).start();
|
||||
|
@ -81,7 +80,6 @@ public class ExternalBrowser implements AutoCloseable {
|
|||
LOG.debug("Waiting for browser to terminate");
|
||||
p.waitFor();
|
||||
int exitValue = p.exitValue();
|
||||
p = null;
|
||||
reader = null;
|
||||
in = null;
|
||||
out = null;
|
||||
|
@ -119,7 +117,6 @@ public class ExternalBrowser implements AutoCloseable {
|
|||
}
|
||||
|
||||
public void executeJavaScript(String javaScript) throws IOException {
|
||||
//LOG.debug("Executing JS {}", javaScript);
|
||||
JSONObject script = new JSONObject();
|
||||
script.put("execute", javaScript);
|
||||
out.write(script.toString().getBytes(UTF_8));
|
||||
|
@ -141,8 +138,7 @@ public class ExternalBrowser implements AutoCloseable {
|
|||
|
||||
private void readBrowserOutput() {
|
||||
LOG.debug("Browser output reader started");
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(in));
|
||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
|
||||
String line;
|
||||
synchronized (browserReadyLock) {
|
||||
browserReady = true;
|
||||
|
@ -150,11 +146,8 @@ public class ExternalBrowser implements AutoCloseable {
|
|||
}
|
||||
while( !Thread.interrupted() && (line = br.readLine()) != null ) {
|
||||
LOG.debug("Browser output: {}", line);
|
||||
if(!line.startsWith("{")) {
|
||||
} else {
|
||||
if(messageListener != null) {
|
||||
messageListener.accept(line);
|
||||
}
|
||||
if (line.startsWith("{") && messageListener != null) {
|
||||
messageListener.accept(line);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -166,12 +166,10 @@ public class Player {
|
|||
// create threads, which read stdout and stderr of the player process. these are needed,
|
||||
// because otherwise the internal buffer for these streams fill up and block the process
|
||||
Thread std = new Thread(new StreamRedirector(playerProcess.getInputStream(), OutputStream.nullOutputStream()));
|
||||
//Thread std = new Thread(new StreamRedirectThread(playerProcess.getInputStream(), System.out));
|
||||
std.setName("Player stdout pipe");
|
||||
std.setDaemon(true);
|
||||
std.start();
|
||||
Thread err = new Thread(new StreamRedirector(playerProcess.getErrorStream(), OutputStream.nullOutputStream()));
|
||||
//Thread err = new Thread(new StreamRedirectThread(playerProcess.getErrorStream(), System.err));
|
||||
err.setName("Player stderr pipe");
|
||||
err.setDaemon(true);
|
||||
err.start();
|
||||
|
|
|
@ -22,7 +22,7 @@ import javafx.scene.layout.StackPane;
|
|||
import javafx.stage.Popup;
|
||||
|
||||
public class PreviewPopupHandler implements EventHandler<MouseEvent> {
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(PreviewPopupHandler.class);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PreviewPopupHandler.class);
|
||||
|
||||
private static final int offset = 10;
|
||||
private long timeForPopupOpen = TimeUnit.SECONDS.toMillis(1);
|
||||
|
@ -67,11 +67,11 @@ public class PreviewPopupHandler implements EventHandler<MouseEvent> {
|
|||
} else if(event.getEventType() == MouseEvent.MOUSE_ENTERED) {
|
||||
popup.setX(event.getScreenX()+ offset);
|
||||
popup.setY(event.getScreenY()+ offset);
|
||||
JavaFxModel model = getModel(event);
|
||||
if(model != null) {
|
||||
JavaFxModel newModel = getModel(event);
|
||||
if(newModel != null) {
|
||||
closeCountdown = -1;
|
||||
boolean modelChanged = model != this.model;
|
||||
this.model = model;
|
||||
boolean modelChanged = newModel != this.model;
|
||||
this.model = newModel;
|
||||
if(popup.isShowing()) {
|
||||
openCountdown = -1;
|
||||
if(modelChanged) {
|
||||
|
@ -97,15 +97,15 @@ public class PreviewPopupHandler implements EventHandler<MouseEvent> {
|
|||
@SuppressWarnings("unchecked")
|
||||
TableRow<JavaFxModel> row = (TableRow<JavaFxModel>) event.getSource();
|
||||
TableView<JavaFxModel> table = row.getTableView();
|
||||
double offset = 0;
|
||||
double columnOffset = 0;
|
||||
double width = 0;
|
||||
for (TableColumn<JavaFxModel, ?> col : table.getColumns()) {
|
||||
offset += width;
|
||||
columnOffset += width;
|
||||
width = col.getWidth();
|
||||
if(Objects.equals(col.getId(), "preview")) {
|
||||
Point2D screenToLocal = table.screenToLocal(event.getScreenX(), event.getScreenY());
|
||||
double x = screenToLocal.getX();
|
||||
return x >= offset && x <= offset + width;
|
||||
return x >= columnOffset && x <= columnOffset + width;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -176,6 +176,7 @@ public class PreviewPopupHandler implements EventHandler<MouseEvent> {
|
|||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
LOG.error("PreviewPopupTimer interrupted");
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.util.Optional;
|
|||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Function;
|
||||
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.recorder.download.StreamSource;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
|
@ -19,9 +20,10 @@ import javafx.stage.Stage;
|
|||
public class StreamSourceSelectionDialog {
|
||||
private static final StreamSource BEST = new BestStreamSource();
|
||||
|
||||
private StreamSourceSelectionDialog() {}
|
||||
private StreamSourceSelectionDialog() {
|
||||
}
|
||||
|
||||
public static void show(Scene parent, Model model, Function<Model,Void> onSuccess, Function<Throwable, Void> onFail) {
|
||||
public static void show(Scene parent, Model model, Function<Model, Void> onSuccess, Function<Throwable, Void> onFail) {
|
||||
Task<List<StreamSource>> selectStreamSource = new Task<List<StreamSource>>() {
|
||||
@Override
|
||||
protected List<StreamSource> call() throws Exception {
|
||||
|
@ -35,7 +37,7 @@ public class StreamSourceSelectionDialog {
|
|||
List<StreamSource> sources;
|
||||
try {
|
||||
sources = selectStreamSource.get();
|
||||
int selectedIndex = model.getStreamUrlIndex() > -1 ? Math.min(model.getStreamUrlIndex(), sources.size()-1) : sources.size()-1;
|
||||
int selectedIndex = model.getStreamUrlIndex() > -1 ? Math.min(model.getStreamUrlIndex(), sources.size() - 1) : sources.size() - 1;
|
||||
ChoiceDialog<StreamSource> choiceDialog = new ChoiceDialog<>(sources.get(selectedIndex), sources);
|
||||
choiceDialog.setTitle("Stream Quality");
|
||||
choiceDialog.setHeaderText("Select your preferred stream quality");
|
||||
|
@ -45,7 +47,7 @@ public class StreamSourceSelectionDialog {
|
|||
InputStream icon = Dialogs.class.getResourceAsStream("/icon.png");
|
||||
stage.getIcons().add(new Image(icon));
|
||||
Optional<StreamSource> selectedSource = choiceDialog.showAndWait();
|
||||
if(selectedSource.isPresent()) {
|
||||
if (selectedSource.isPresent()) {
|
||||
int index = -1;
|
||||
if (selectedSource.get() != BEST) {
|
||||
index = sources.indexOf(selectedSource.get());
|
||||
|
@ -61,7 +63,7 @@ public class StreamSourceSelectionDialog {
|
|||
}
|
||||
});
|
||||
selectStreamSource.setOnFailed(e -> onFail.apply(selectStreamSource.getException()));
|
||||
new Thread(selectStreamSource).start();
|
||||
GlobalThreadPool.submit(selectStreamSource);
|
||||
}
|
||||
|
||||
private static class BestStreamSource extends StreamSource {
|
||||
|
|
|
@ -7,7 +7,7 @@ import java.util.concurrent.ExecutionException;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ctbrec.Model;
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.sites.Site;
|
||||
import javafx.application.Platform;
|
||||
import javafx.concurrent.Task;
|
||||
|
@ -19,11 +19,11 @@ import javafx.stage.Stage;
|
|||
|
||||
public class TipDialog extends TextInputDialog {
|
||||
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(TipDialog.class);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TipDialog.class);
|
||||
private Site site;
|
||||
private Scene parent;
|
||||
|
||||
public TipDialog(Scene parent, Site site, Model model) {
|
||||
public TipDialog(Scene parent, Site site) {
|
||||
this.parent = parent;
|
||||
this.site = site;
|
||||
setTitle("Send Tip");
|
||||
|
@ -32,7 +32,7 @@ public class TipDialog extends TextInputDialog {
|
|||
setContentText("Amount of tokens to tip:");
|
||||
setResizable(true);
|
||||
getEditor().setDisable(true);
|
||||
if(parent != null) {
|
||||
if (parent != null) {
|
||||
Stage stage = (Stage) getDialogPane().getScene().getWindow();
|
||||
stage.getScene().getStylesheets().addAll(parent.getStylesheets());
|
||||
}
|
||||
|
@ -56,14 +56,14 @@ public class TipDialog extends TextInputDialog {
|
|||
double tokens = get();
|
||||
Platform.runLater(() -> {
|
||||
if (tokens <= 0) {
|
||||
String msg = "Do you want to buy tokens now?\n\nIf you agree, "+site.getName()+" will open in a browser. "
|
||||
String msg = "Do you want to buy tokens now?\n\nIf you agree, " + site.getName() + " will open in a browser. "
|
||||
+ "The used address is an affiliate link, which supports me, but doesn't cost you anything more.";
|
||||
Alert buyTokens = new AutosizeAlert(Alert.AlertType.CONFIRMATION, msg, parent, ButtonType.NO, ButtonType.YES);
|
||||
buyTokens.setTitle("No tokens");
|
||||
buyTokens.setHeaderText("You don't have any tokens");
|
||||
buyTokens.showAndWait();
|
||||
TipDialog.this.close();
|
||||
if(buyTokens.getResult() == ButtonType.YES) {
|
||||
if (buyTokens.getResult() == ButtonType.YES) {
|
||||
DesktopIntegration.open(site.getAffiliateLink());
|
||||
}
|
||||
} else {
|
||||
|
@ -72,13 +72,20 @@ public class TipDialog extends TextInputDialog {
|
|||
setHeaderText("Current token balance: " + df.format(tokens));
|
||||
}
|
||||
});
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
LOG.error("Couldn't retrieve account balance", e);
|
||||
showErrorDialog(e);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
handleExcetion(e);
|
||||
} catch (ExecutionException e) {
|
||||
handleExcetion(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
new Thread(task).start();
|
||||
GlobalThreadPool.submit(task);
|
||||
}
|
||||
|
||||
private void handleExcetion(Exception e) {
|
||||
LOG.error("Couldn't retrieve account balance", e);
|
||||
showErrorDialog(e);
|
||||
}
|
||||
|
||||
private void showErrorDialog(Throwable throwable) {
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.event.EventBusHolder;
|
||||
import ctbrec.sites.Site;
|
||||
import javafx.application.Platform;
|
||||
|
@ -19,7 +20,7 @@ import javafx.scene.control.Tooltip;
|
|||
|
||||
public class TokenLabel extends Label {
|
||||
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(TokenLabel.class);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TokenLabel.class);
|
||||
private double tokens = -1;
|
||||
private Site site;
|
||||
|
||||
|
@ -72,17 +73,24 @@ public class TokenLabel extends Label {
|
|||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
double tokens = get();
|
||||
tokens = get();
|
||||
update(tokens);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
LOG.error("Couldn't retrieve account balance", e);
|
||||
Platform.runLater(() -> {
|
||||
setText("Tokens: error");
|
||||
setTooltip(new Tooltip(e.getMessage()));
|
||||
});
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
handleException(e);
|
||||
} catch (ExecutionException e) {
|
||||
handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleException(Exception e) {
|
||||
LOG.error("Couldn't retrieve account balance", e);
|
||||
Platform.runLater(() -> {
|
||||
setText("Tokens: error");
|
||||
setTooltip(new Tooltip(e.getMessage()));
|
||||
});
|
||||
}
|
||||
};
|
||||
new Thread(task).start();
|
||||
GlobalThreadPool.submit(task);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import java.util.stream.Collectors;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
|
@ -70,6 +71,6 @@ public class CheckModelAccountAction {
|
|||
});
|
||||
}
|
||||
});
|
||||
new Thread(checker).start();
|
||||
GlobalThreadPool.submit(checker);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import ctbrec.Config;
|
|||
import ctbrec.Model;
|
||||
import ctbrec.ui.JavaFxModel;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Cursor;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.TableView;
|
||||
|
@ -30,23 +29,21 @@ public class EditNotesAction {
|
|||
|
||||
public void execute() {
|
||||
source.setCursor(Cursor.WAIT);
|
||||
new Thread(() -> Platform.runLater(() -> {
|
||||
String notes = Config.getInstance().getSettings().modelNotes.getOrDefault(model.getUrl(), "");
|
||||
Optional<String> newNotes = Dialogs.showTextInput(source.getScene(), "Model Notes", "Notes for " + model.getName(), notes);
|
||||
newNotes.ifPresent(n -> {
|
||||
if (!n.trim().isEmpty()) {
|
||||
Config.getInstance().getSettings().modelNotes.put(model.getUrl(), n);
|
||||
} else {
|
||||
Config.getInstance().getSettings().modelNotes.remove(model.getUrl());
|
||||
}
|
||||
try {
|
||||
Config.getInstance().save();
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Couldn't save config", e);
|
||||
}
|
||||
});
|
||||
table.refresh();
|
||||
source.setCursor(Cursor.DEFAULT);
|
||||
})).start();
|
||||
String notes = Config.getInstance().getSettings().modelNotes.getOrDefault(model.getUrl(), "");
|
||||
Optional<String> newNotes = Dialogs.showTextInput(source.getScene(), "Model Notes", "Notes for " + model.getName(), notes);
|
||||
newNotes.ifPresent(n -> {
|
||||
if (!n.trim().isEmpty()) {
|
||||
Config.getInstance().getSettings().modelNotes.put(model.getUrl(), n);
|
||||
} else {
|
||||
Config.getInstance().getSettings().modelNotes.remove(model.getUrl());
|
||||
}
|
||||
try {
|
||||
Config.getInstance().save();
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Couldn't save config", e);
|
||||
}
|
||||
});
|
||||
table.refresh();
|
||||
source.setCursor(Cursor.DEFAULT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,13 +2,9 @@ package ctbrec.ui.action;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.Model;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Cursor;
|
||||
|
@ -16,9 +12,6 @@ import javafx.scene.Node;
|
|||
|
||||
public class ModelMassEditAction {
|
||||
|
||||
static BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
|
||||
static ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 10, TimeUnit.MINUTES, queue);
|
||||
|
||||
protected List<? extends Model> models;
|
||||
protected Consumer<Model> action;
|
||||
protected Node source;
|
||||
|
@ -42,7 +35,7 @@ public class ModelMassEditAction {
|
|||
Consumer<Model> cb = Objects.requireNonNull(callback, "Callback is null, call execute() instead");
|
||||
source.setCursor(Cursor.WAIT);
|
||||
for (Model model : models) {
|
||||
threadPool.submit(() -> {
|
||||
GlobalThreadPool.submit(() -> {
|
||||
action.accept(model);
|
||||
cb.accept(model);
|
||||
Platform.runLater(() -> source.setCursor(Cursor.DEFAULT));
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.io.File;
|
|||
import java.time.Instant;
|
||||
|
||||
import ctbrec.Config;
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.Settings.DirectoryStructure;
|
||||
import ctbrec.ui.DesktopIntegration;
|
||||
|
@ -26,7 +27,7 @@ public class OpenRecordingsDir {
|
|||
File fileForRecording = Config.getInstance().getFileForRecording(selectedModel, ".mp4", Instant.now());
|
||||
final File dir = getModelDirectory(fileForRecording);
|
||||
if (dir.exists()) {
|
||||
new Thread(() -> DesktopIntegration.open(dir)).start();
|
||||
GlobalThreadPool.submit(() -> DesktopIntegration.open(dir));
|
||||
} else {
|
||||
Dialogs.showError(source.getScene(), "Directory does not exist", "There are no recordings for this model", null);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ctbrec.ui.action;
|
||||
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import javafx.application.Platform;
|
||||
|
@ -20,7 +21,7 @@ public class ToggleRecordingAction {
|
|||
|
||||
public void execute() {
|
||||
toggleButton.setCursor(Cursor.WAIT);
|
||||
Thread t = new Thread(() -> {
|
||||
GlobalThreadPool.submit(() -> {
|
||||
try {
|
||||
if (pause) {
|
||||
recorder.pause();
|
||||
|
@ -36,7 +37,5 @@ public class ToggleRecordingAction {
|
|||
Platform.runLater(() -> toggleButton.setCursor(Cursor.DEFAULT));
|
||||
}
|
||||
});
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ import java.util.Optional;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.ui.action.PlayAction;
|
||||
|
@ -167,7 +168,7 @@ public class SearchPopoverTreeList extends PopoverTreeList<Model> implements Pop
|
|||
follow = new Button("Follow");
|
||||
follow.setOnAction(evt -> {
|
||||
setCursor(Cursor.WAIT);
|
||||
new Thread(new Task<Boolean>() {
|
||||
GlobalThreadPool.submit(new Task<Boolean>() {
|
||||
@Override
|
||||
protected Boolean call() throws Exception {
|
||||
model.getSite().login();
|
||||
|
@ -183,12 +184,12 @@ public class SearchPopoverTreeList extends PopoverTreeList<Model> implements Pop
|
|||
}
|
||||
Platform.runLater(() -> setCursor(Cursor.DEFAULT));
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
});
|
||||
record = new Button("Record");
|
||||
record.setOnAction(evt -> {
|
||||
setCursor(Cursor.WAIT);
|
||||
new Thread(new Task<Void>() {
|
||||
GlobalThreadPool.submit(new Task<Void>() {
|
||||
@Override
|
||||
protected Void call() throws Exception {
|
||||
recorder.addModel(model);
|
||||
|
@ -199,7 +200,7 @@ public class SearchPopoverTreeList extends PopoverTreeList<Model> implements Pop
|
|||
protected void done() {
|
||||
Platform.runLater(() -> setCursor(Cursor.DEFAULT));
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
});
|
||||
getChildren().addAll(thumb, title, follow, record);
|
||||
|
||||
|
@ -296,12 +297,12 @@ public class SearchPopoverTreeList extends PopoverTreeList<Model> implements Pop
|
|||
|
||||
@Override
|
||||
protected double computePrefHeight(double width) {
|
||||
return thumbSize + 20;
|
||||
return thumbSize + 20.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double computeMaxHeight(double width) {
|
||||
return thumbSize + 20;
|
||||
return thumbSize + 20.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ctbrec.Config;
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.io.HttpException;
|
||||
import ctbrec.recorder.download.StreamSource;
|
||||
|
@ -79,7 +80,7 @@ public class StreamPreview extends StackPane {
|
|||
double w = Config.getInstance().getSettings().thumbWidth;
|
||||
double h = w / aspect;
|
||||
resizeTo(w, h);
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) { /* nothing to do */ }
|
||||
}
|
||||
|
||||
if(future != null && !future.isDone()) {
|
||||
|
@ -157,14 +158,14 @@ public class StreamPreview extends StackPane {
|
|||
running = false;
|
||||
MediaPlayer old = videoPlayer;
|
||||
Future<?> oldFuture = future;
|
||||
new Thread(() -> {
|
||||
GlobalThreadPool.submit(() -> {
|
||||
if(oldFuture != null && !oldFuture.isDone()) {
|
||||
oldFuture.cancel(true);
|
||||
}
|
||||
if(old != null) {
|
||||
old.dispose();
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
}
|
||||
|
||||
private void onError(MediaPlayer videoPlayer) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ctbrec.ui.controls;
|
||||
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.KeyValue;
|
||||
import javafx.animation.Timeline;
|
||||
|
@ -13,6 +14,8 @@ import javafx.stage.StageStyle;
|
|||
import javafx.util.Duration;
|
||||
|
||||
public final class Toast {
|
||||
private Toast() {}
|
||||
|
||||
public static void makeText(Scene owner, String toastMsg, int toastDelay, int fadeInDelay, int fadeOutDelay) {
|
||||
Stage toastStage = new Stage();
|
||||
toastStage.initOwner(owner.getWindow());
|
||||
|
@ -35,20 +38,18 @@ public final class Toast {
|
|||
Timeline fadeInTimeline = new Timeline();
|
||||
KeyFrame fadeInKey1 = new KeyFrame(Duration.millis(fadeInDelay), new KeyValue(toastStage.getScene().getRoot().opacityProperty(), 1));
|
||||
fadeInTimeline.getKeyFrames().add(fadeInKey1);
|
||||
fadeInTimeline.setOnFinished((ae) -> {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(toastDelay);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
Timeline fadeOutTimeline = new Timeline();
|
||||
KeyFrame fadeOutKey1 = new KeyFrame(Duration.millis(fadeOutDelay), new KeyValue(toastStage.getScene().getRoot().opacityProperty(), 0));
|
||||
fadeOutTimeline.getKeyFrames().add(fadeOutKey1);
|
||||
fadeOutTimeline.setOnFinished((aeb) -> toastStage.close());
|
||||
fadeOutTimeline.play();
|
||||
}).start();
|
||||
});
|
||||
fadeInTimeline.setOnFinished(ae -> GlobalThreadPool.submit(() -> {
|
||||
try {
|
||||
Thread.sleep(toastDelay);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
Timeline fadeOutTimeline = new Timeline();
|
||||
KeyFrame fadeOutKey1 = new KeyFrame(Duration.millis(fadeOutDelay), new KeyValue(toastStage.getScene().getRoot().opacityProperty(), 0));
|
||||
fadeOutTimeline.getKeyFrames().add(fadeOutKey1);
|
||||
fadeOutTimeline.setOnFinished(aeb -> toastStage.close());
|
||||
fadeOutTimeline.play();
|
||||
}));
|
||||
fadeInTimeline.play();
|
||||
}
|
||||
}
|
|
@ -1,7 +1,16 @@
|
|||
package ctbrec.ui.news;
|
||||
|
||||
import static ctbrec.io.HttpConstants.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import com.squareup.moshi.JsonAdapter;
|
||||
import com.squareup.moshi.Moshi;
|
||||
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.io.HttpException;
|
||||
import ctbrec.ui.CamrecApplication;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
|
@ -14,12 +23,6 @@ import javafx.scene.control.Tab;
|
|||
import javafx.scene.layout.VBox;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import static ctbrec.io.HttpConstants.USER_AGENT;
|
||||
|
||||
public class NewsTab extends Tab implements TabSelectionListener {
|
||||
private static final String ACCESS_TOKEN = "a2804d73a89951a22e0f8483a6fcec8943afd88b7ba17c459c095aa9e6f94fd0";
|
||||
|
@ -36,7 +39,7 @@ public class NewsTab extends Tab implements TabSelectionListener {
|
|||
|
||||
@Override
|
||||
public void selected() {
|
||||
new Thread(this::loadToots).start();
|
||||
GlobalThreadPool.submit(this::loadToots);
|
||||
}
|
||||
|
||||
private void loadToots() {
|
||||
|
|
|
@ -22,7 +22,7 @@ import okhttp3.HttpUrl;
|
|||
|
||||
public class BongaCamsElectronLoginDialog {
|
||||
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(BongaCamsElectronLoginDialog.class);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(BongaCamsElectronLoginDialog.class);
|
||||
public static final String DOMAIN = "bongacams.com";
|
||||
public static final String URL = BongaCams.baseUrl + "/login";
|
||||
private CookieJar cookieJar;
|
||||
|
@ -40,18 +40,18 @@ public class BongaCamsElectronLoginDialog {
|
|||
msg.put("config", config);
|
||||
browser.run(msg, msgHandler);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IOException("Couldn't wait for login dialog", e);
|
||||
} finally {
|
||||
browser.close();
|
||||
}
|
||||
}
|
||||
|
||||
private Consumer<String> msgHandler = (line) -> {
|
||||
private Consumer<String> msgHandler = line -> {
|
||||
if(!line.startsWith("{")) {
|
||||
System.err.println(line);
|
||||
LOG.error("Didn't received a JSON object {}", line);
|
||||
} else {
|
||||
JSONObject json = new JSONObject(line);
|
||||
//LOG.debug("Browser: {}", json.toString(2));
|
||||
if(json.has("url")) {
|
||||
String url = json.getString("url");
|
||||
if(url.endsWith("/login")) {
|
||||
|
@ -82,16 +82,16 @@ public class BongaCamsElectronLoginDialog {
|
|||
}
|
||||
|
||||
if(json.has("cookies")) {
|
||||
JSONArray _cookies = json.getJSONArray("cookies");
|
||||
for (int i = 0; i < _cookies.length(); i++) {
|
||||
JSONObject cookie = _cookies.getJSONObject(i);
|
||||
JSONArray cookiesFromBrowser = json.getJSONArray("cookies");
|
||||
for (int i = 0; i < cookiesFromBrowser.length(); i++) {
|
||||
JSONObject cookie = cookiesFromBrowser.getJSONObject(i);
|
||||
if(cookie.getString("domain").contains(DOMAIN)) {
|
||||
Builder b = new Cookie.Builder()
|
||||
.path(cookie.getString("path"))
|
||||
.domain(DOMAIN)
|
||||
.name(cookie.getString("name"))
|
||||
.value(cookie.getString("value"))
|
||||
.expiresAt(Double.valueOf(cookie.optDouble("expirationDate")).longValue());
|
||||
.expiresAt((long) cookie.optDouble("expirationDate"));
|
||||
if(cookie.optBoolean("hostOnly")) {
|
||||
b.hostOnlyDomain(DOMAIN);
|
||||
}
|
||||
|
@ -108,8 +108,7 @@ public class BongaCamsElectronLoginDialog {
|
|||
}
|
||||
|
||||
try {
|
||||
URL _url = new URL(url);
|
||||
if (Objects.equals(_url.getPath(), "/")) {
|
||||
if (Objects.equals(new URL(url).getPath(), "/")) {
|
||||
browser.close();
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
package ctbrec.ui.sites.bonga;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ctbrec.sites.bonga.BongaCams;
|
||||
import ctbrec.sites.bonga.BongaCamsHttpClient;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import ctbrec.ui.sites.AbstractSiteUi;
|
||||
import ctbrec.ui.sites.ConfigUI;
|
||||
import ctbrec.ui.tabs.TabProvider;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
public class BongaCamsSiteUi extends AbstractSiteUi {
|
||||
|
||||
|
@ -39,37 +38,20 @@ public class BongaCamsSiteUi extends AbstractSiteUi {
|
|||
@Override
|
||||
public synchronized boolean login() throws IOException {
|
||||
boolean automaticLogin = bongaCams.login();
|
||||
if(automaticLogin) {
|
||||
if (automaticLogin) {
|
||||
return true;
|
||||
} else {
|
||||
BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
|
||||
// login with external browser window
|
||||
try {
|
||||
new Thread(() -> {
|
||||
// login with external browser window
|
||||
try {
|
||||
new BongaCamsElectronLoginDialog(bongaCams.getHttpClient().getCookieJar());
|
||||
} catch (Exception e1) {
|
||||
LOG.error("Error logging in with external browser", e1);
|
||||
Dialogs.showError("Login error", "Couldn't login to " + bongaCams.getName(), e1);
|
||||
}
|
||||
|
||||
try {
|
||||
queue.put(true);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
LOG.error("Error while signaling termination", e);
|
||||
}
|
||||
}).start();
|
||||
queue.take();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
LOG.error("Error while waiting for login dialog to close", e);
|
||||
throw new IOException(e);
|
||||
new BongaCamsElectronLoginDialog(bongaCams.getHttpClient().getCookieJar());
|
||||
} catch (Exception e1) {
|
||||
LOG.error("Error logging in with external browser", e1);
|
||||
Dialogs.showError("Login error", "Couldn't login to " + bongaCams.getName(), e1);
|
||||
}
|
||||
|
||||
BongaCamsHttpClient httpClient = (BongaCamsHttpClient)bongaCams.getHttpClient();
|
||||
BongaCamsHttpClient httpClient = (BongaCamsHttpClient) bongaCams.getHttpClient();
|
||||
boolean loggedIn = httpClient.checkLoginSuccess();
|
||||
if(loggedIn) {
|
||||
if (loggedIn) {
|
||||
LOG.info("Logged in. User ID is {}", httpClient.getUserId());
|
||||
} else {
|
||||
LOG.info("Login failed");
|
||||
|
|
|
@ -22,7 +22,7 @@ import okhttp3.HttpUrl;
|
|||
|
||||
public class Cam4ElectronLoginDialog {
|
||||
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(Cam4ElectronLoginDialog.class);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Cam4ElectronLoginDialog.class);
|
||||
public static final String DOMAIN = "cam4.com";
|
||||
public static final String URL = Cam4.BASE_URI + "/login";
|
||||
private CookieJar cookieJar;
|
||||
|
@ -40,15 +40,16 @@ public class Cam4ElectronLoginDialog {
|
|||
msg.put("config", config);
|
||||
browser.run(msg, msgHandler);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IOException("Couldn't wait for login dialog", e);
|
||||
} finally {
|
||||
browser.close();
|
||||
}
|
||||
}
|
||||
|
||||
private Consumer<String> msgHandler = (line) -> {
|
||||
private Consumer<String> msgHandler = line -> {
|
||||
if(!line.startsWith("{")) {
|
||||
System.err.println(line);
|
||||
LOG.error("Didn't received a JSON object {}", line);
|
||||
} else {
|
||||
JSONObject json = new JSONObject(line);
|
||||
if(json.has("url")) {
|
||||
|
@ -75,11 +76,10 @@ public class Cam4ElectronLoginDialog {
|
|||
}
|
||||
|
||||
if(json.has("cookies")) {
|
||||
JSONArray _cookies = json.getJSONArray("cookies");
|
||||
JSONArray cookiesFromBrowser = json.getJSONArray("cookies");
|
||||
try {
|
||||
URL _url = new URL(url);
|
||||
for (int i = 0; i < _cookies.length(); i++) {
|
||||
JSONObject cookie = _cookies.getJSONObject(i);
|
||||
for (int i = 0; i < cookiesFromBrowser.length(); i++) {
|
||||
JSONObject cookie = cookiesFromBrowser.getJSONObject(i);
|
||||
if(cookie.getString("domain").contains("cam4")) {
|
||||
String domain = cookie.getString("domain");
|
||||
if(domain.startsWith(".")) {
|
||||
|
@ -91,12 +91,8 @@ public class Cam4ElectronLoginDialog {
|
|||
cookieJar.saveFromResponse(HttpUrl.parse(Cam4.BASE_URI), Collections.singletonList(c));
|
||||
}
|
||||
}
|
||||
if (Objects.equals(_url.getPath(), "/")) {
|
||||
try {
|
||||
browser.close();
|
||||
} catch(IOException e) {
|
||||
LOG.error("Couldn't send close request to browser", e);
|
||||
}
|
||||
if (Objects.equals(new URL(url).getPath(), "/")) {
|
||||
closeBrowser();
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
LOG.error("Couldn't parse new url {}", url, e);
|
||||
|
@ -112,7 +108,7 @@ public class Cam4ElectronLoginDialog {
|
|||
.domain(domain)
|
||||
.name(cookie.getString("name"))
|
||||
.value(cookie.getString("value"))
|
||||
.expiresAt(Double.valueOf(cookie.optDouble("expirationDate")).longValue());
|
||||
.expiresAt((long) cookie.optDouble("expirationDate"));
|
||||
if(cookie.optBoolean("hostOnly")) {
|
||||
b.hostOnlyDomain(domain);
|
||||
}
|
||||
|
@ -124,4 +120,12 @@ public class Cam4ElectronLoginDialog {
|
|||
}
|
||||
return b.build();
|
||||
}
|
||||
|
||||
private void closeBrowser() {
|
||||
try {
|
||||
browser.close();
|
||||
} catch(IOException e) {
|
||||
LOG.error("Couldn't send close request to browser", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package ctbrec.ui.sites.cam4;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -13,10 +11,9 @@ import ctbrec.ui.controls.Dialogs;
|
|||
import ctbrec.ui.sites.AbstractSiteUi;
|
||||
import ctbrec.ui.sites.ConfigUI;
|
||||
import ctbrec.ui.tabs.TabProvider;
|
||||
import javafx.application.Platform;
|
||||
|
||||
public class Cam4SiteUi extends AbstractSiteUi {
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(Cam4SiteUi.class);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Cam4SiteUi.class);
|
||||
|
||||
private Cam4TabProvider tabProvider;
|
||||
private Cam4ConfigUI configUI;
|
||||
|
@ -44,33 +41,13 @@ public class Cam4SiteUi extends AbstractSiteUi {
|
|||
if (automaticLogin) {
|
||||
return true;
|
||||
} else {
|
||||
|
||||
BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
|
||||
|
||||
Runnable showDialog = () -> {
|
||||
// login with external browser
|
||||
try {
|
||||
new Cam4ElectronLoginDialog(cam4.getHttpClient().getCookieJar());
|
||||
} catch (Exception e1) {
|
||||
LOG.error("Error logging in with external browser", e1);
|
||||
Dialogs.showError("Login error", "Couldn't login to " + cam4.getName(), e1);
|
||||
}
|
||||
|
||||
try {
|
||||
queue.put(true);
|
||||
} catch (InterruptedException e) {
|
||||
LOG.error("Error while signaling termination", e);
|
||||
}
|
||||
};
|
||||
|
||||
Platform.runLater(showDialog);
|
||||
// login with external browser
|
||||
try {
|
||||
queue.take();
|
||||
} catch (InterruptedException e) {
|
||||
LOG.error("Error while waiting for login dialog to close", e);
|
||||
throw new IOException(e);
|
||||
new Cam4ElectronLoginDialog(cam4.getHttpClient().getCookieJar());
|
||||
} catch (Exception e1) {
|
||||
LOG.error("Error logging in with external browser", e1);
|
||||
Dialogs.showError("Login error", "Couldn't login to " + cam4.getName(), e1);
|
||||
}
|
||||
|
||||
Cam4HttpClient httpClient = (Cam4HttpClient) cam4.getHttpClient();
|
||||
boolean loggedIn = httpClient.checkLoginSuccess();
|
||||
return loggedIn;
|
||||
|
|
|
@ -10,7 +10,6 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.nodes.Element;
|
||||
|
@ -43,14 +42,11 @@ public class Cam4UpdateService extends PaginatedScheduledService {
|
|||
this.url = url;
|
||||
this.loginRequired = loginRequired;
|
||||
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = new Thread(r);
|
||||
t.setDaemon(true);
|
||||
t.setName("ThumbOverviewTab UpdateService");
|
||||
return t;
|
||||
}
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor(r -> {
|
||||
Thread t = new Thread(r);
|
||||
t.setDaemon(true);
|
||||
t.setName("ThumbOverviewTab UpdateService");
|
||||
return t;
|
||||
});
|
||||
setExecutor(executor);
|
||||
}
|
||||
|
@ -60,16 +56,16 @@ public class Cam4UpdateService extends PaginatedScheduledService {
|
|||
return new Task<List<Model>>() {
|
||||
@Override
|
||||
public List<Model> call() throws IOException {
|
||||
if(loginRequired && StringUtil.isBlank(Config.getInstance().getSettings().cam4Username)) {
|
||||
if (loginRequired && StringUtil.isBlank(Config.getInstance().getSettings().cam4Username)) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
String url = Cam4UpdateService.this.url + "&page=" + page;
|
||||
LOG.debug("Fetching page {}", url);
|
||||
if(loginRequired) {
|
||||
String pageUrl = Cam4UpdateService.this.url + "&page=" + page;
|
||||
LOG.debug("Fetching page {}", pageUrl);
|
||||
if (loginRequired) {
|
||||
SiteUiFactory.getUi(site).login();
|
||||
}
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.url(pageUrl)
|
||||
.header(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage())
|
||||
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
|
||||
.build();
|
||||
|
@ -91,7 +87,7 @@ public class Cam4UpdateService extends PaginatedScheduledService {
|
|||
model.setPreview("https://snapshots.xcdnpro.com/thumbnails/" + model.getName() + "?s=" + System.currentTimeMillis());
|
||||
model.setDescription(parseDesription(boxHtml));
|
||||
model.setOnlineState(ONLINE);
|
||||
if(boxHtml.contains("In private show")) {
|
||||
if (boxHtml.contains("In private show")) {
|
||||
model.setOnlineState(PRIVATE);
|
||||
}
|
||||
models.add(model);
|
||||
|
|
|
@ -5,7 +5,6 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -21,7 +20,7 @@ import okhttp3.Response;
|
|||
|
||||
public class ChaturbateUpdateService extends PaginatedScheduledService {
|
||||
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(ChaturbateUpdateService.class);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ChaturbateUpdateService.class);
|
||||
private String url;
|
||||
private boolean loginRequired;
|
||||
private Chaturbate chaturbate;
|
||||
|
@ -31,14 +30,11 @@ public class ChaturbateUpdateService extends PaginatedScheduledService {
|
|||
this.loginRequired = loginRequired;
|
||||
this.chaturbate = chaturbate;
|
||||
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = new Thread(r);
|
||||
t.setDaemon(true);
|
||||
t.setName("ThumbOverviewTab UpdateService");
|
||||
return t;
|
||||
}
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor(r -> {
|
||||
Thread t = new Thread(r);
|
||||
t.setDaemon(true);
|
||||
t.setName("ThumbOverviewTab UpdateService");
|
||||
return t;
|
||||
});
|
||||
setExecutor(executor);
|
||||
}
|
||||
|
@ -51,12 +47,12 @@ public class ChaturbateUpdateService extends PaginatedScheduledService {
|
|||
if(loginRequired && !chaturbate.credentialsAvailable()) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
String url = ChaturbateUpdateService.this.url + "?page="+page+"&keywords=&_=" + System.currentTimeMillis();
|
||||
LOG.debug("Fetching page {}", url);
|
||||
String pageUrl = ChaturbateUpdateService.this.url + "?page="+page+"&keywords=&_=" + System.currentTimeMillis();
|
||||
LOG.debug("Fetching page {}", pageUrl);
|
||||
if(loginRequired) {
|
||||
SiteUiFactory.getUi(chaturbate).login();
|
||||
}
|
||||
Request request = new Request.Builder().url(url).build();
|
||||
Request request = new Request.Builder().url(pageUrl).build();
|
||||
Response response = chaturbate.getHttpClient().execute(request);
|
||||
if (response.isSuccessful()) {
|
||||
List<Model> models = ChaturbateModelParser.parseModels(chaturbate, response.body().string());
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.io.IOException;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.sites.fc2live.Fc2Live;
|
||||
import ctbrec.sites.fc2live.Fc2Model;
|
||||
|
@ -16,7 +17,7 @@ import ctbrec.ui.sites.ConfigUI;
|
|||
import ctbrec.ui.tabs.TabProvider;
|
||||
|
||||
public class Fc2LiveSiteUi extends AbstractSiteUi {
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(Fc2LiveSiteUi.class);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Fc2LiveSiteUi.class);
|
||||
private Fc2Live fc2live;
|
||||
private Fc2TabProvider tabProvider;
|
||||
private Fc2LiveConfigUI configUi;
|
||||
|
@ -44,10 +45,10 @@ public class Fc2LiveSiteUi extends AbstractSiteUi {
|
|||
|
||||
@Override
|
||||
public boolean play(Model model) {
|
||||
new Thread(() -> {
|
||||
GlobalThreadPool.submit(() -> {
|
||||
Fc2Model m;
|
||||
if(model instanceof JavaFxModel) {
|
||||
m = (Fc2Model) ((JavaFxModel)model).getDelegate();
|
||||
if (model instanceof JavaFxModel) {
|
||||
m = (Fc2Model) ((JavaFxModel) model).getDelegate();
|
||||
} else {
|
||||
m = (Fc2Model) model;
|
||||
}
|
||||
|
@ -55,12 +56,20 @@ public class Fc2LiveSiteUi extends AbstractSiteUi {
|
|||
m.openWebsocket();
|
||||
LOG.debug("Starting player for {}", model);
|
||||
Player.play(model, false);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
handleException(e);
|
||||
} catch (IOException e) {
|
||||
handleException(e);
|
||||
} finally {
|
||||
m.closeWebsocket();
|
||||
} catch (InterruptedException | IOException e) {
|
||||
LOG.error("Error playing the stream", e);
|
||||
Dialogs.showError("Player", "Error playing the stream", e);
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
private void handleException(Exception e) {
|
||||
LOG.error("Error playing the stream", e);
|
||||
Dialogs.showError("Player", "Error playing the stream", e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package ctbrec.ui.sites.jasmin;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -17,7 +15,7 @@ import ctbrec.ui.tabs.TabProvider;
|
|||
|
||||
public class LiveJasminSiteUi extends AbstractSiteUi {
|
||||
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(LiveJasminSiteUi.class);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(LiveJasminSiteUi.class);
|
||||
private LiveJasmin liveJasmin;
|
||||
private LiveJasminTabProvider tabProvider;
|
||||
private LiveJasminConfigUi configUi;
|
||||
|
@ -44,43 +42,27 @@ public class LiveJasminSiteUi extends AbstractSiteUi {
|
|||
// renew login every 30 min
|
||||
long now = System.currentTimeMillis();
|
||||
boolean renew = false;
|
||||
if((now - lastLoginTime) > TimeUnit.MINUTES.toMillis(30)) {
|
||||
if ((now - lastLoginTime) > TimeUnit.MINUTES.toMillis(30)) {
|
||||
renew = true;
|
||||
}
|
||||
|
||||
boolean automaticLogin = liveJasmin.login();
|
||||
if(automaticLogin && !renew) {
|
||||
if (automaticLogin && !renew) {
|
||||
return true;
|
||||
} else {
|
||||
lastLoginTime = System.currentTimeMillis();
|
||||
BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
|
||||
|
||||
new Thread (() -> {
|
||||
// login with external browser window
|
||||
try {
|
||||
new LiveJasminElectronLoginDialog(liveJasmin.getHttpClient().getCookieJar());
|
||||
} catch (Exception e1) {
|
||||
LOG.error("Error logging in with external browser", e1);
|
||||
Dialogs.showError("Login error", "Couldn't login to " + liveJasmin.getName(), e1);
|
||||
}
|
||||
|
||||
try {
|
||||
queue.put(true);
|
||||
} catch (InterruptedException e) {
|
||||
LOG.error("Error while signaling termination", e);
|
||||
}
|
||||
}).start();
|
||||
|
||||
// login with external browser window
|
||||
try {
|
||||
queue.take();
|
||||
} catch (InterruptedException e) {
|
||||
LOG.error("Error while waiting for login dialog to close", e);
|
||||
throw new IOException(e);
|
||||
new LiveJasminElectronLoginDialog(liveJasmin.getHttpClient().getCookieJar());
|
||||
} catch (Exception e1) {
|
||||
LOG.error("Error logging in with external browser", e1);
|
||||
Dialogs.showError("Login error", "Couldn't login to " + liveJasmin.getName(), e1);
|
||||
}
|
||||
|
||||
LiveJasminHttpClient httpClient = (LiveJasminHttpClient)liveJasmin.getHttpClient();
|
||||
LiveJasminHttpClient httpClient = (LiveJasminHttpClient) liveJasmin.getHttpClient();
|
||||
boolean loggedIn = httpClient.checkLoginSuccess();
|
||||
if(loggedIn) {
|
||||
if (loggedIn) {
|
||||
LOG.info("Logged in");
|
||||
} else {
|
||||
LOG.info("Login failed");
|
||||
|
|
|
@ -33,6 +33,7 @@ import com.iheartradio.m3u8.ParseException;
|
|||
import com.iheartradio.m3u8.PlaylistException;
|
||||
|
||||
import ctbrec.Config;
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.Settings;
|
||||
import ctbrec.StringUtil;
|
||||
|
@ -353,7 +354,7 @@ public class MyFreeCamsTableTab extends Tab implements TabSelectionListener {
|
|||
|
||||
if (Objects.equals(System.getenv("CTBREC_DEV"), "1")) {
|
||||
MenuItem debug = new MenuItem("debug");
|
||||
debug.setOnAction(e -> new Thread(() -> {
|
||||
debug.setOnAction(e -> GlobalThreadPool.submit(() -> {
|
||||
for (Model m : selectedModels) {
|
||||
try {
|
||||
List<StreamSource> sources = m.getStreamSources();
|
||||
|
@ -365,7 +366,7 @@ public class MyFreeCamsTableTab extends Tab implements TabSelectionListener {
|
|||
LOG.error("Couldn't get stream sources", e1);
|
||||
}
|
||||
}
|
||||
}).start());
|
||||
}));
|
||||
menu.getItems().add(debug);
|
||||
}
|
||||
|
||||
|
@ -464,7 +465,7 @@ public class MyFreeCamsTableTab extends Tab implements TabSelectionListener {
|
|||
|
||||
private String escape(Property<?> prop) {
|
||||
String value = prop.getValue() != null ? prop.getValue().toString() : "";
|
||||
return "\"" + value.replaceAll("\"", "\"\"") + "\"";
|
||||
return "\"" + value.replace("\"", "\"\"") + "\"";
|
||||
}
|
||||
|
||||
private void showColumnSelection(ActionEvent evt) {
|
||||
|
@ -566,7 +567,7 @@ public class MyFreeCamsTableTab extends Tab implements TabSelectionListener {
|
|||
if(!file.exists()) {
|
||||
return;
|
||||
}
|
||||
String json = new String(Files.readAllBytes(file.toPath()), "utf-8");
|
||||
String json = new String(Files.readAllBytes(file.toPath()), UTF_8);
|
||||
JSONArray data = new JSONArray(json);
|
||||
for (int i = 0; i < data.length(); i++) {
|
||||
try {
|
||||
|
@ -701,7 +702,6 @@ public class MyFreeCamsTableTab extends Tab implements TabSelectionListener {
|
|||
setProperty(continent, Optional.ofNullable(st.getM()).map(ctbrec.sites.mfc.Model::getContinent));
|
||||
setProperty(occupation, Optional.ofNullable(st.getU()).map(User::getOccupation));
|
||||
int flags = Optional.ofNullable(st.getM()).map(ctbrec.sites.mfc.Model::getFlags).orElse(0);
|
||||
//isHd.set((flags & 1024) == 1024);
|
||||
isWebrtc.set((flags & 524288) == 524288);
|
||||
isHd.set(Optional.ofNullable(st.getU()).map(User::getPhase).orElse("z").equalsIgnoreCase("a"));
|
||||
flagsProperty.setValue(flags);
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package ctbrec.ui.sites.showup;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -44,33 +42,17 @@ public class ShowupSiteUi extends AbstractSiteUi {
|
|||
if (automaticLogin) {
|
||||
return true;
|
||||
} else {
|
||||
BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
|
||||
// login with external browser window
|
||||
try {
|
||||
new Thread(() -> {
|
||||
// login with external browser window
|
||||
try {
|
||||
new ShowupElectronLoginDialog(site.getHttpClient().getCookieJar());
|
||||
} catch (Exception e1) {
|
||||
LOG.error("Error logging in with external browser", e1);
|
||||
Dialogs.showError("Login error", "Couldn't login to " + site.getName(), e1);
|
||||
}
|
||||
|
||||
try {
|
||||
queue.put(true);
|
||||
} catch (InterruptedException e) {
|
||||
LOG.error("Error while signaling termination", e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}).start();
|
||||
queue.take();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IOException(e);
|
||||
new ShowupElectronLoginDialog(site.getHttpClient().getCookieJar());
|
||||
} catch (Exception e1) {
|
||||
LOG.error("Error logging in with external browser", e1);
|
||||
Dialogs.showError("Login error", "Couldn't login to " + site.getName(), e1);
|
||||
}
|
||||
|
||||
ShowupHttpClient httpClient = (ShowupHttpClient)site.getHttpClient();
|
||||
ShowupHttpClient httpClient = (ShowupHttpClient) site.getHttpClient();
|
||||
boolean loggedIn = httpClient.checkLoginSuccess();
|
||||
if(loggedIn) {
|
||||
if (loggedIn) {
|
||||
LOG.info("Logged in");
|
||||
} else {
|
||||
LOG.info("Login failed");
|
||||
|
@ -78,5 +60,4 @@ public class ShowupSiteUi extends AbstractSiteUi {
|
|||
return loggedIn;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package ctbrec.ui.sites.stripchat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -13,7 +11,6 @@ import ctbrec.ui.controls.Dialogs;
|
|||
import ctbrec.ui.sites.AbstractSiteUi;
|
||||
import ctbrec.ui.sites.ConfigUI;
|
||||
import ctbrec.ui.tabs.TabProvider;
|
||||
import javafx.application.Platform;
|
||||
|
||||
public class StripchatSiteUi extends AbstractSiteUi {
|
||||
|
||||
|
@ -45,31 +42,12 @@ public class StripchatSiteUi extends AbstractSiteUi {
|
|||
if (automaticLogin) {
|
||||
return true;
|
||||
} else {
|
||||
|
||||
BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
|
||||
|
||||
Runnable showDialog = () -> {
|
||||
// login with external browser
|
||||
try {
|
||||
new StripchatElectronLoginDialog(site.getHttpClient().getCookieJar());
|
||||
} catch (Exception e1) {
|
||||
LOG.error("Error logging in with external browser", e1);
|
||||
Dialogs.showError("Login error", "Couldn't login to " + site.getName(), e1);
|
||||
}
|
||||
|
||||
try {
|
||||
queue.put(true);
|
||||
} catch (InterruptedException e) {
|
||||
LOG.error("Error while signaling termination", e);
|
||||
}
|
||||
};
|
||||
|
||||
Platform.runLater(showDialog);
|
||||
// login with external browser
|
||||
try {
|
||||
queue.take();
|
||||
} catch (InterruptedException e) {
|
||||
LOG.error("Error while waiting for login dialog to close", e);
|
||||
throw new IOException(e);
|
||||
new StripchatElectronLoginDialog(site.getHttpClient().getCookieJar());
|
||||
} catch (Exception e1) {
|
||||
LOG.error("Error logging in with external browser", e1);
|
||||
Dialogs.showError("Login error", "Couldn't login to " + site.getName(), e1);
|
||||
}
|
||||
|
||||
StripchatHttpClient httpClient = (StripchatHttpClient) site.getHttpClient();
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ctbrec.Config;
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.Recording;
|
||||
import ctbrec.Recording.State;
|
||||
|
@ -496,9 +497,9 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
|
|||
|
||||
private void openContactSheet(JavaFxRecording recording) {
|
||||
if (config.getSettings().localRecording) {
|
||||
recording.getContactSheet().ifPresent(f -> new Thread(() -> DesktopIntegration.open(f)).start());
|
||||
recording.getContactSheet().ifPresent(f -> GlobalThreadPool.submit(() -> DesktopIntegration.open(f)));
|
||||
} else {
|
||||
recording.getContactSheet().ifPresent(f -> new Thread(() -> {
|
||||
recording.getContactSheet().ifPresent(f -> GlobalThreadPool.submit(() -> {
|
||||
File target;
|
||||
try {
|
||||
target = File.createTempFile("cs_", ".jpg");
|
||||
|
@ -516,7 +517,7 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
|
|||
} catch (IOException | InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e) {
|
||||
Dialogs.showError(getTabPane().getScene(), "Download Error", "An error occurred while downloading the contact sheet", e);
|
||||
}
|
||||
}).start());
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -526,7 +527,7 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
|
|||
Optional<String> newNote = Dialogs.showTextInput(source.getScene(), "Recording Notes", "", notes);
|
||||
if (newNote.isPresent()) {
|
||||
table.setCursor(Cursor.WAIT);
|
||||
Thread backgroundThread = new Thread(() -> {
|
||||
GlobalThreadPool.submit(() -> {
|
||||
List<Exception> exceptions = new ArrayList<>();
|
||||
try {
|
||||
recording.setNote(newNote.get());
|
||||
|
@ -542,13 +543,12 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
|
|||
});
|
||||
}
|
||||
});
|
||||
backgroundThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
private void pin(List<JavaFxRecording> recordings) {
|
||||
table.setCursor(Cursor.WAIT);
|
||||
Thread backgroundThread = new Thread(() -> {
|
||||
GlobalThreadPool.submit(() -> {
|
||||
List<Exception> exceptions = new ArrayList<>();
|
||||
try {
|
||||
for (JavaFxRecording javaFxRecording : recordings) {
|
||||
|
@ -569,12 +569,11 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
|
|||
});
|
||||
}
|
||||
});
|
||||
backgroundThread.start();
|
||||
}
|
||||
|
||||
private void unpin(List<JavaFxRecording> recordings) {
|
||||
table.setCursor(Cursor.WAIT);
|
||||
Thread backgroundThread = new Thread(() -> {
|
||||
GlobalThreadPool.submit(() -> {
|
||||
List<Exception> exceptions = new ArrayList<>();
|
||||
try {
|
||||
for (JavaFxRecording javaFxRecording : recordings) {
|
||||
|
@ -595,7 +594,6 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
|
|||
});
|
||||
}
|
||||
});
|
||||
backgroundThread.start();
|
||||
}
|
||||
|
||||
private void jumpToNextModel(KeyCode code) {
|
||||
|
@ -646,11 +644,11 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
|
|||
|
||||
private void onOpenDirectory(JavaFxRecording first) {
|
||||
File tsFile = first.getAbsoluteFile();
|
||||
new Thread(() -> DesktopIntegration.open(tsFile.getParent())).start();
|
||||
GlobalThreadPool.submit(() -> DesktopIntegration.open(tsFile.getParent()));
|
||||
}
|
||||
|
||||
private void triggerPostProcessing(List<JavaFxRecording> recs) {
|
||||
new Thread(() -> {
|
||||
GlobalThreadPool.submit(() -> {
|
||||
for (JavaFxRecording rec : recs) {
|
||||
try {
|
||||
recorder.rerunPostProcessing(rec.getDelegate());
|
||||
|
@ -659,7 +657,7 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
|
|||
LOG.error("Error while starting post-processing", e1);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
}
|
||||
|
||||
private void download(Recording recording) {
|
||||
|
@ -761,12 +759,12 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
|
|||
}
|
||||
|
||||
private void play(Recording recording) {
|
||||
new Thread(() -> {
|
||||
GlobalThreadPool.submit(() -> {
|
||||
boolean started = Player.play(recording);
|
||||
if (started && Config.getInstance().getSettings().showPlayerStarting) {
|
||||
Platform.runLater(() -> Toast.makeText(getTabPane().getScene(), "Starting Player", 2000, 500, 500));
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
}
|
||||
|
||||
private void play(Model model) {
|
||||
|
|
|
@ -8,8 +8,6 @@ import java.util.Locale;
|
|||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
@ -107,7 +105,6 @@ public class ThumbCell extends StackPane {
|
|||
private ObservableList<Node> thumbCellList;
|
||||
private boolean mouseHovering = false;
|
||||
private boolean recording = false;
|
||||
private static ExecutorService imageLoadingThreadPool = Executors.newFixedThreadPool(30);
|
||||
static LoadingCache<Model, int[]> resolutionCache = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(5, TimeUnit.MINUTES)
|
||||
.maximumSize(10000)
|
||||
|
@ -388,7 +385,7 @@ public class ThumbCell extends StackPane {
|
|||
if (!Objects.equals(System.getenv("CTBREC_DEV"), "1")) {
|
||||
boolean updateThumbs = Config.getInstance().getSettings().updateThumbnails;
|
||||
if (updateThumbs || iv.getImage() == null) {
|
||||
imageLoadingThreadPool.submit(createThumbDownload(url));
|
||||
GlobalThreadPool.submit(createThumbDownload(url));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -513,7 +510,7 @@ public class ThumbCell extends StackPane {
|
|||
|
||||
void pauseResumeAction(boolean pause) {
|
||||
setCursor(Cursor.WAIT);
|
||||
new Thread(() -> {
|
||||
GlobalThreadPool.submit(() -> {
|
||||
try {
|
||||
if (pause) {
|
||||
recorder.suspendRecording(model);
|
||||
|
@ -533,11 +530,11 @@ public class ThumbCell extends StackPane {
|
|||
} finally {
|
||||
Platform.runLater(() -> setCursor(Cursor.DEFAULT));
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
}
|
||||
|
||||
private void startStopActionAsync(Model model, boolean start) {
|
||||
new Thread(() -> {
|
||||
GlobalThreadPool.submit(() -> {
|
||||
try {
|
||||
if (start) {
|
||||
recorder.addModel(model);
|
||||
|
@ -553,7 +550,7 @@ public class ThumbCell extends StackPane {
|
|||
} finally {
|
||||
Platform.runLater(() -> setCursor(Cursor.DEFAULT));
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
}
|
||||
|
||||
CompletableFuture<Boolean> follow(boolean follow) {
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ctbrec.Config;
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.event.EventBusHolder;
|
||||
import ctbrec.recorder.Recorder;
|
||||
|
@ -299,7 +300,7 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
|||
return;
|
||||
}
|
||||
searchTask = new ThumbOverviewTabSearchTask(site, popover, popoverTreeList, newValue);
|
||||
new Thread(searchTask).start();
|
||||
GlobalThreadPool.submit(searchTask);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -602,7 +603,7 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
|||
private MenuItem createTipMenuItem(ThumbCell cell) {
|
||||
MenuItem sendTip = new MenuItem("Send Tip");
|
||||
sendTip.setOnAction(e -> {
|
||||
TipDialog tipDialog = new TipDialog(getTabPane().getScene(), site, cell.getModel());
|
||||
TipDialog tipDialog = new TipDialog(getTabPane().getScene(), site);
|
||||
tipDialog.showAndWait();
|
||||
String tipText = tipDialog.getResult();
|
||||
if(tipText != null) {
|
||||
|
|
|
@ -8,7 +8,7 @@ import java.util.concurrent.Future;
|
|||
|
||||
public class GlobalThreadPool {
|
||||
|
||||
private static ExecutorService threadPool = Executors.newCachedThreadPool(r -> {
|
||||
private static ExecutorService threadPool = Executors.newFixedThreadPool(30, r -> {
|
||||
Thread t = new Thread(r);
|
||||
t.setDaemon(true);
|
||||
t.setName("GlobalWorker-" + UUID.randomUUID().toString().substring(0, 8));
|
||||
|
|
|
@ -82,9 +82,6 @@ public class MergedFfmpegHlsDownload extends AbstractHlsDownload {
|
|||
public void start() throws IOException {
|
||||
try {
|
||||
running = true;
|
||||
Thread.currentThread().setName("Download " + model.getName());
|
||||
super.startTime = Instant.now();
|
||||
|
||||
String segments = getSegmentPlaylistUrl(model);
|
||||
|
||||
Files.createDirectories(targetFile.getParentFile().toPath());
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ctbrec.Config;
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.io.HttpClient;
|
||||
import okhttp3.Request;
|
||||
|
@ -78,9 +79,9 @@ public class LiveJasminTippingWebSocket {
|
|||
LOG.trace("relay <-- {} T{}", model.getName(), text);
|
||||
JSONObject event = new JSONObject(text);
|
||||
if (event.optString("event").equals("accept")) {
|
||||
new Thread(() -> {
|
||||
GlobalThreadPool.submit(() -> {
|
||||
sendToRelay("{\"event\":\"connectSharedObject\",\"name\":\"data/chat_so\"}");
|
||||
}).start();
|
||||
});
|
||||
} else if(event.optString("event").equals("call")) {
|
||||
String func = event.optString("funcName");
|
||||
if (func.equals("setName")) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ctbrec.recorder.server;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.*;
|
||||
import static javax.servlet.http.HttpServletResponse.*;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
|
@ -53,6 +54,7 @@ import org.slf4j.LoggerFactory;
|
|||
import com.google.common.base.Objects;
|
||||
|
||||
import ctbrec.Config;
|
||||
import ctbrec.NotLoggedInExcetion;
|
||||
import ctbrec.Version;
|
||||
import ctbrec.event.EventBusHolder;
|
||||
import ctbrec.event.EventHandler;
|
||||
|
@ -124,7 +126,7 @@ public class HttpServer {
|
|||
if (success) {
|
||||
LOG.info("Successfully logged in to {}", site.getName());
|
||||
} else {
|
||||
throw new RuntimeException("Login returned false");
|
||||
throw new NotLoggedInExcetion("Login returned false");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.info("Login to {} failed", site.getName());
|
||||
|
@ -243,7 +245,7 @@ public class HttpServer {
|
|||
byte[] hmac = Optional.ofNullable(HttpServer.this.config.getSettings().key).orElse(new byte[0]);
|
||||
try {
|
||||
JSONObject response = new JSONObject();
|
||||
response.put("hmac", new String(hmac, "utf-8"));
|
||||
response.put("hmac", new String(hmac, UTF_8));
|
||||
resp.getOutputStream().println(response.toString());
|
||||
} catch (Exception e) {
|
||||
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
|
|
|
@ -1,23 +1,7 @@
|
|||
package ctbrec.recorder.server;
|
||||
|
||||
import com.squareup.moshi.JsonAdapter;
|
||||
import com.squareup.moshi.Moshi;
|
||||
import ctbrec.Config;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.Recording;
|
||||
import ctbrec.io.BandwidthMeter;
|
||||
import ctbrec.io.FileJsonAdapter;
|
||||
import ctbrec.io.InstantJsonAdapter;
|
||||
import ctbrec.io.ModelJsonAdapter;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.sites.Site;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import static javax.servlet.http.HttpServletResponse.*;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidKeyException;
|
||||
|
@ -27,7 +11,27 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static javax.servlet.http.HttpServletResponse.*;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.squareup.moshi.JsonAdapter;
|
||||
import com.squareup.moshi.Moshi;
|
||||
|
||||
import ctbrec.Config;
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.Recording;
|
||||
import ctbrec.io.BandwidthMeter;
|
||||
import ctbrec.io.FileJsonAdapter;
|
||||
import ctbrec.io.InstantJsonAdapter;
|
||||
import ctbrec.io.ModelJsonAdapter;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.sites.Site;
|
||||
|
||||
public class RecorderServlet extends AbstractCtbrecServlet {
|
||||
|
||||
|
@ -87,24 +91,24 @@ public class RecorderServlet extends AbstractCtbrecServlet {
|
|||
resp.getWriter().write(response);
|
||||
break;
|
||||
case "stop":
|
||||
new Thread(() -> {
|
||||
GlobalThreadPool.submit(() -> {
|
||||
try {
|
||||
recorder.stopRecording(request.model);
|
||||
} catch (InvalidKeyException | NoSuchAlgorithmException | IllegalStateException | IOException e) {
|
||||
LOG.error("Couldn't stop recording for model {}", request.model, e);
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
response = "{\"status\": \"success\", \"msg\": \"Stopping recording\"}";
|
||||
resp.getWriter().write(response);
|
||||
break;
|
||||
case "stopAt":
|
||||
new Thread(() -> {
|
||||
GlobalThreadPool.submit(() -> {
|
||||
try {
|
||||
recorder.stopRecordingAt(request.model);
|
||||
} catch (InvalidKeyException | NoSuchAlgorithmException | IllegalStateException | IOException e) {
|
||||
LOG.error("Couldn't stop recording for model {}", request.model, e);
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
response = "{\"status\": \"success\", \"msg\": \"Stopping recording\"}";
|
||||
resp.getWriter().write(response);
|
||||
break;
|
||||
|
@ -189,13 +193,13 @@ public class RecorderServlet extends AbstractCtbrecServlet {
|
|||
break;
|
||||
case "suspend":
|
||||
LOG.debug("Suspend recording for model {} - {}", request.model.getName(), request.model.getUrl());
|
||||
new Thread(() -> {
|
||||
GlobalThreadPool.submit(() -> {
|
||||
try {
|
||||
recorder.suspendRecording(request.model);
|
||||
} catch (InvalidKeyException | NoSuchAlgorithmException | IllegalStateException | IOException e) {
|
||||
LOG.error("Couldn't suspend recording for model {}", request.model, e);
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
response = "{\"status\": \"success\", \"msg\": \"Suspending recording\"}";
|
||||
resp.getWriter().write(response);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue