forked from j62/ctbrec
Compare commits
40 Commits
Author | SHA1 | Date |
---|---|---|
|
ceceb4dd6e | |
|
1c1066d399 | |
|
a4984b02f1 | |
|
98d6ece1a6 | |
|
b1e1f9b2c7 | |
|
45434afd96 | |
|
2a0a3ad4a6 | |
|
e7aae593cc | |
|
2622305951 | |
|
41ddc25cc9 | |
|
809325ebac | |
|
e58f491887 | |
|
ec4e5e9ba2 | |
|
819c80ca30 | |
|
674a84dcb0 | |
|
733cdc6da4 | |
|
f59bf26d54 | |
|
6dbbde9d80 | |
|
6aec3a2354 | |
|
4cf096ff1a | |
|
9c1cd6b073 | |
|
bb91a319c4 | |
|
0dc8bbc870 | |
|
3f1a8f5b0a | |
|
bb9e679970 | |
|
3f4ae44bae | |
|
daa192c42b | |
|
c47d7f7077 | |
|
d747e4cf7a | |
|
4753ad2eb4 | |
|
713b95d05b | |
|
1a51c1b1bb | |
|
9b0acfa1a2 | |
|
226a8316e2 | |
|
f49f2dae43 | |
|
ad386bd5df | |
|
9a5a469ad0 | |
|
7a1d0ae197 | |
|
a92c8b7753 | |
|
20ebde9b73 |
|
@ -7,4 +7,4 @@
|
||||||
.project
|
.project
|
||||||
*/.factorypath
|
*/.factorypath
|
||||||
**/.antlr/
|
**/.antlr/
|
||||||
*.code-workspace
|
*.code-workspace
|
||||||
|
|
17
CHANGELOG.md
17
CHANGELOG.md
|
@ -1,20 +1,3 @@
|
||||||
5.3.4-J62
|
|
||||||
========================
|
|
||||||
Current Good working copy after chaturbate reverting their changes. Chaturbate Video and audio currently working.
|
|
||||||
* jre bundled (in releases) (fixed permissions) (linux and macos)
|
|
||||||
* updated ffmpeg (in releases) (fixed permissions) (windows, linux and macos)
|
|
||||||
* fixed run script permissions (linux and macos)
|
|
||||||
* bump ver
|
|
||||||
* all builds checked
|
|
||||||
|
|
||||||
5.3.3-J62
|
|
||||||
========================
|
|
||||||
Reverted for chaturbate reverting their changes. Chaturbate Video and audio currently working.
|
|
||||||
* jre bundled (in releases)
|
|
||||||
* flirt4free fix - "topic" no longer sent, replaced with empty string
|
|
||||||
* bump ver
|
|
||||||
* all builds checked
|
|
||||||
|
|
||||||
5.3.0
|
5.3.0
|
||||||
========================
|
========================
|
||||||
* Added menu entry to force recording of models without changing the prio
|
* Added menu entry to force recording of models without changing the prio
|
||||||
|
|
|
@ -22,6 +22,7 @@ Ether: 0x2e687A5628ff16c8f9624A914C1f727000089C3A <br>
|
||||||
Solana: Z5YwNPkLheSHuaSJjyHhg3L8UxjpJPt5WU6vu4hFsNR <br>
|
Solana: Z5YwNPkLheSHuaSJjyHhg3L8UxjpJPt5WU6vu4hFsNR <br>
|
||||||
Monero: 47tjD1z63wu3FEnDCvWnFaRAZbpDKc3Ys1WCbgzvB2Gg8XbqU8bARpcCC37mWzuWBAeZPu2UGY4TAcYGhb6fptoTR8X9vjc
|
Monero: 47tjD1z63wu3FEnDCvWnFaRAZbpDKc3Ys1WCbgzvB2Gg8XbqU8bARpcCC37mWzuWBAeZPu2UGY4TAcYGhb6fptoTR8X9vjc
|
||||||
|
|
||||||
|
|
||||||
## A free recording software for different camsites. Currently supported: BongaCams, Cam4, CamSoda, Chaturbate, FC2Live, LiveJasmin, MyFreeCams, Streamate
|
## A free recording software for different camsites. Currently supported: BongaCams, Cam4, CamSoda, Chaturbate, FC2Live, LiveJasmin, MyFreeCams, Streamate
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -9,6 +9,7 @@ import ctbrec.Settings.ProxyType;
|
||||||
import ctbrec.docs.DocServer;
|
import ctbrec.docs.DocServer;
|
||||||
import ctbrec.recorder.Recorder;
|
import ctbrec.recorder.Recorder;
|
||||||
import ctbrec.sites.Site;
|
import ctbrec.sites.Site;
|
||||||
|
import ctbrec.sites.chaturbate.Chaturbate;
|
||||||
import ctbrec.ui.DesktopIntegration;
|
import ctbrec.ui.DesktopIntegration;
|
||||||
import ctbrec.ui.SiteUI;
|
import ctbrec.ui.SiteUI;
|
||||||
import ctbrec.ui.SiteUiFactory;
|
import ctbrec.ui.SiteUiFactory;
|
||||||
|
@ -16,6 +17,8 @@ import ctbrec.ui.controls.range.DiscreteRange;
|
||||||
import ctbrec.ui.settings.api.*;
|
import ctbrec.ui.settings.api.*;
|
||||||
import ctbrec.ui.sites.ConfigUI;
|
import ctbrec.ui.sites.ConfigUI;
|
||||||
import ctbrec.ui.tabs.TabSelectionListener;
|
import ctbrec.ui.tabs.TabSelectionListener;
|
||||||
|
import ctbrec.ui.tabs.ThumbOverviewTab;
|
||||||
|
import ctbrec.ui.sites.chaturbate.ChaturbateTabProvider;
|
||||||
import javafx.animation.FadeTransition;
|
import javafx.animation.FadeTransition;
|
||||||
import javafx.animation.PauseTransition;
|
import javafx.animation.PauseTransition;
|
||||||
import javafx.animation.Transition;
|
import javafx.animation.Transition;
|
||||||
|
@ -30,13 +33,16 @@ import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
import javafx.scene.control.TextInputDialog;
|
import javafx.scene.control.TextInputDialog;
|
||||||
|
import javafx.scene.control.TabPane;
|
||||||
import javafx.scene.layout.*;
|
import javafx.scene.layout.*;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
|
import javafx.scene.Parent;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -70,6 +76,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
private SimpleBooleanProperty determineResolution;
|
private SimpleBooleanProperty determineResolution;
|
||||||
private SimpleBooleanProperty chooseStreamQuality;
|
private SimpleBooleanProperty chooseStreamQuality;
|
||||||
private SimpleBooleanProperty confirmationDialogs;
|
private SimpleBooleanProperty confirmationDialogs;
|
||||||
|
private SimpleBooleanProperty naCamsOnly;
|
||||||
private SimpleBooleanProperty livePreviews;
|
private SimpleBooleanProperty livePreviews;
|
||||||
private SimpleBooleanProperty monitorClipboard;
|
private SimpleBooleanProperty monitorClipboard;
|
||||||
private SimpleListProperty<String> startTab;
|
private SimpleListProperty<String> startTab;
|
||||||
|
@ -152,7 +159,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
private void initializeProperties() {
|
private void initializeProperties() {
|
||||||
flaresolverrApiUrl = new SimpleStringProperty(null, "flaresolverr.apiUrl", settings.flaresolverr.apiUrl);
|
flaresolverrApiUrl = new SimpleStringProperty(null, "flaresolverr.apiUrl", settings.flaresolverr.apiUrl);
|
||||||
flaresolverrTimeoutInMillis = new SimpleIntegerProperty(null, "flaresolverr.timeoutInMillis", settings.flaresolverr.timeoutInMillis);
|
flaresolverrTimeoutInMillis = new SimpleIntegerProperty(null, "flaresolverr.timeoutInMillis", settings.flaresolverr.timeoutInMillis);
|
||||||
flaresolverrUseForDomains = new SimpleJoinedStringListProperty(null, "flaresolverr.useForDomains", "\n",
|
flaresolverrUseForDomains = new SimpleJoinedStringListProperty(null, "flaresolverr.useForDomains", "\n",
|
||||||
FXCollections.observableList(settings.flaresolverr.useForDomains));
|
FXCollections.observableList(settings.flaresolverr.useForDomains));
|
||||||
httpUserAgent = new SimpleStringProperty(null, "httpUserAgent", settings.httpUserAgent);
|
httpUserAgent = new SimpleStringProperty(null, "httpUserAgent", settings.httpUserAgent);
|
||||||
httpUserAgentMobile = new SimpleStringProperty(null, "httpUserAgentMobile", settings.httpUserAgentMobile);
|
httpUserAgentMobile = new SimpleStringProperty(null, "httpUserAgentMobile", settings.httpUserAgentMobile);
|
||||||
|
@ -207,6 +214,14 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
onlineCheckSkipsPausedModels = new SimpleBooleanProperty(null, "onlineCheckSkipsPausedModels", settings.onlineCheckSkipsPausedModels);
|
onlineCheckSkipsPausedModels = new SimpleBooleanProperty(null, "onlineCheckSkipsPausedModels", settings.onlineCheckSkipsPausedModels);
|
||||||
fastScrollSpeed = new SimpleBooleanProperty(null, "fastScrollSpeed", settings.fastScrollSpeed);
|
fastScrollSpeed = new SimpleBooleanProperty(null, "fastScrollSpeed", settings.fastScrollSpeed);
|
||||||
confirmationDialogs = new SimpleBooleanProperty(null, "confirmationForDangerousActions", settings.confirmationForDangerousActions);
|
confirmationDialogs = new SimpleBooleanProperty(null, "confirmationForDangerousActions", settings.confirmationForDangerousActions);
|
||||||
|
naCamsOnly = new SimpleBooleanProperty(null, "filterNAcamsOnly", settings.filterNAcamsOnly);
|
||||||
|
naCamsOnly.addListener((obs, oldValue, newValue) -> {
|
||||||
|
settings.filterNAcamsOnly = newValue;
|
||||||
|
Config.getInstance().getSettings().filterNAcamsOnly = newValue; // Ensure the config is updated
|
||||||
|
saveConfig();
|
||||||
|
refreshChaturbateTabs(); // Refresh tabs when the setting changes
|
||||||
|
});
|
||||||
|
|
||||||
useHlsdl = new SimpleBooleanProperty(null, "useHlsdl", settings.useHlsdl);
|
useHlsdl = new SimpleBooleanProperty(null, "useHlsdl", settings.useHlsdl);
|
||||||
hlsdlExecutable = new SimpleFileProperty(null, "hlsdlExecutable", settings.hlsdlExecutable);
|
hlsdlExecutable = new SimpleFileProperty(null, "hlsdlExecutable", settings.hlsdlExecutable);
|
||||||
recentlyWatched = new SimpleBooleanProperty(null, "recentlyWatched", settings.recentlyWatched);
|
recentlyWatched = new SimpleBooleanProperty(null, "recentlyWatched", settings.recentlyWatched);
|
||||||
|
@ -230,6 +245,48 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
httpClientMaxRequestsPerHost = new SimpleIntegerProperty(null, "httpClientMaxRequestsPerHost", settings.httpClientMaxRequestsPerHost);
|
httpClientMaxRequestsPerHost = new SimpleIntegerProperty(null, "httpClientMaxRequestsPerHost", settings.httpClientMaxRequestsPerHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void refreshChaturbateTabs() {
|
||||||
|
System.out.println("Refreshing Chaturbate Tabs..."); // Debugging output
|
||||||
|
|
||||||
|
// Find the Chaturbate tab
|
||||||
|
Tab chaturbateTab = null;
|
||||||
|
for (Tab tab : getTabPane().getTabs()) {
|
||||||
|
if (tab.getText().equalsIgnoreCase("Chaturbate")) {
|
||||||
|
chaturbateTab = tab;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chaturbateTab == null) {
|
||||||
|
System.out.println("Chaturbate tab not found! Cannot refresh.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chaturbateTab instanceof ThumbOverviewTab overviewTab) {
|
||||||
|
overviewTab.getUpdateService().reset(); // Reset update service for new URLs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the tab container inside the Chaturbate tab
|
||||||
|
if (chaturbateTab.getContent() instanceof Parent parent) {
|
||||||
|
var chaturbateTabsContainer = parent.lookup(".tab-pane");
|
||||||
|
if (chaturbateTabsContainer instanceof TabPane chaturbateTabPane) {
|
||||||
|
// Remove all existing Chaturbate sub-tabs
|
||||||
|
chaturbateTabPane.getTabs().clear();
|
||||||
|
|
||||||
|
// Get updated Chaturbate tabs and add them inside the Chaturbate section
|
||||||
|
var newTabs = SiteUiFactory.getUi(new Chaturbate()).getTabProvider().getTabs(getTabPane().getScene());
|
||||||
|
chaturbateTabPane.getTabs().addAll(newTabs);
|
||||||
|
|
||||||
|
System.out.println("Chaturbate tabs refreshed!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Could not find the correct TabPane inside Chaturbate tab!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void createGui() {
|
private void createGui() {
|
||||||
var postProcessingStepPanel = new PostProcessingStepPanel(config);
|
var postProcessingStepPanel = new PostProcessingStepPanel(config);
|
||||||
var variablesHelpButton = createHelpButton("Variables", "http://localhost:5689/docs/PostProcessing.md#variables");
|
var variablesHelpButton = createHelpButton("Variables", "http://localhost:5689/docs/PostProcessing.md#variables");
|
||||||
|
@ -257,6 +314,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
Setting.of("Start minimized", startMinimized, "Start the app minimized to the tray, automatically activates \"Minimize to tray\""),
|
Setting.of("Start minimized", startMinimized, "Start the app minimized to the tray, automatically activates \"Minimize to tray\""),
|
||||||
Setting.of("Add models from clipboard", monitorClipboard, "Monitor clipboard for model URLs and automatically add them to the recorder").needsRestart(),
|
Setting.of("Add models from clipboard", monitorClipboard, "Monitor clipboard for model URLs and automatically add them to the recorder").needsRestart(),
|
||||||
Setting.of("Show confirmation dialogs", confirmationDialogs, "Show confirmation dialogs for irreversible actions"),
|
Setting.of("Show confirmation dialogs", confirmationDialogs, "Show confirmation dialogs for irreversible actions"),
|
||||||
|
Setting.of("Show only North America Cams", naCamsOnly, "Show only North America Cams").needsRestart(),
|
||||||
Setting.of("Recording tab per site", recordedModelsPerSite, "Add a Recording tab for each site").needsRestart(),
|
Setting.of("Recording tab per site", recordedModelsPerSite, "Add a Recording tab for each site").needsRestart(),
|
||||||
Setting.of("Check for new versions at startup", checkForUpdates, "Search for updates every startup"),
|
Setting.of("Check for new versions at startup", checkForUpdates, "Search for updates every startup"),
|
||||||
Setting.of("Start Tab", startTab)),
|
Setting.of("Start Tab", startTab)),
|
||||||
|
@ -272,7 +330,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
Setting.of("Browser", browserOverride),
|
Setting.of("Browser", browserOverride),
|
||||||
Setting.of("Start parameters", browserParams),
|
Setting.of("Start parameters", browserParams),
|
||||||
Setting.of("Force use (ignore default browser)", forceBrowserOverride, "Default behaviour will fallback to OS default if the above browser fails")),
|
Setting.of("Force use (ignore default browser)", forceBrowserOverride, "Default behaviour will fallback to OS default if the above browser fails")),
|
||||||
|
|
||||||
Group.of("Flaresolverr",
|
Group.of("Flaresolverr",
|
||||||
Setting.of("API URL", flaresolverrApiUrl),
|
Setting.of("API URL", flaresolverrApiUrl),
|
||||||
Setting.of("Request timeout", flaresolverrTimeoutInMillis),
|
Setting.of("Request timeout", flaresolverrTimeoutInMillis),
|
||||||
|
@ -343,11 +401,11 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
Category.of("Advanced / Devtools",
|
Category.of("Advanced / Devtools",
|
||||||
Group.of("Networking",
|
Group.of("Networking",
|
||||||
Setting.of("Playlist request timeout (ms)", playlistRequestTimeout, "Timeout in ms for playlist requests"),
|
Setting.of("Playlist request timeout (ms)", playlistRequestTimeout, "Timeout in ms for playlist requests"),
|
||||||
Setting.of("Max requests", httpClientMaxRequests,
|
Setting.of("Max requests", httpClientMaxRequests,
|
||||||
"The maximum number of requests to execute concurrently. Above this requests queue in memory,\n" + //
|
"The maximum number of requests to execute concurrently. Above this requests queue in memory,\n" + //
|
||||||
"waiting for the running calls to complete.\n\n" + //
|
"waiting for the running calls to complete.\n\n" + //
|
||||||
"If more than [maxRequests] requests are in flight when this is invoked, those requests will remain in flight."),
|
"If more than [maxRequests] requests are in flight when this is invoked, those requests will remain in flight."),
|
||||||
Setting.of("Max requests per host", httpClientMaxRequestsPerHost,
|
Setting.of("Max requests per host", httpClientMaxRequestsPerHost,
|
||||||
"The maximum number of requests for each host to execute concurrently. This limits requests by\n" + //
|
"The maximum number of requests for each host to execute concurrently. This limits requests by\n" + //
|
||||||
"the URL's host name. Note that concurrent requests to a single IP address may still exceed this\n" + //
|
"the URL's host name. Note that concurrent requests to a single IP address may still exceed this\n" + //
|
||||||
"limit: multiple hostnames may share an IP address or be routed through the same HTTP proxy.\n\n" + //
|
"limit: multiple hostnames may share an IP address or be routed through the same HTTP proxy.\n\n" + //
|
||||||
|
@ -363,7 +421,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
Setting.of("hlsdl executable", hlsdlExecutable, "Path to the hlsdl executable"),
|
Setting.of("hlsdl executable", hlsdlExecutable, "Path to the hlsdl executable"),
|
||||||
Setting.of("Log hlsdl output", loghlsdlOutput, "Log hlsdl output to files in the system's temp directory")),
|
Setting.of("Log hlsdl output", loghlsdlOutput, "Log hlsdl output to files in the system's temp directory")),
|
||||||
Group.of("Miscelaneous",
|
Group.of("Miscelaneous",
|
||||||
Setting.of("Config file saving delay (ms)", configSavingDelayMs,
|
Setting.of("Config file saving delay (ms)", configSavingDelayMs,
|
||||||
"Wait specified number of milliseconds before actually writing config to disk"))));
|
"Wait specified number of milliseconds before actually writing config to disk"))));
|
||||||
Region preferencesView = prefs.getView();
|
Region preferencesView = prefs.getView();
|
||||||
prefs.onRestartRequired(this::showRestartRequired);
|
prefs.onRestartRequired(this::showRestartRequired);
|
||||||
|
@ -667,7 +725,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
|
|
||||||
private static final String DATE_FORMATTER_TOOLTIP = """
|
private static final String DATE_FORMATTER_TOOLTIP = """
|
||||||
Leave empty for system default
|
Leave empty for system default
|
||||||
|
|
||||||
Symbol Meaning Presentation Examples
|
Symbol Meaning Presentation Examples
|
||||||
------ ------- ------------ -------
|
------ ------- ------------ -------
|
||||||
G era text AD; Anno Domini; A
|
G era text AD; Anno Domini; A
|
||||||
|
@ -676,7 +734,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
D day-of-year number 189
|
D day-of-year number 189
|
||||||
M/L month-of-year number/text 7; 07; Jul; July; J
|
M/L month-of-year number/text 7; 07; Jul; July; J
|
||||||
d day-of-month number 10
|
d day-of-month number 10
|
||||||
|
|
||||||
Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter
|
Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter
|
||||||
Y week-based-year year 1996; 96
|
Y week-based-year year 1996; 96
|
||||||
w week-of-week-based-year number 27
|
w week-of-week-based-year number 27
|
||||||
|
@ -684,12 +742,12 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
E day-of-week text Tue; Tuesday; T
|
E day-of-week text Tue; Tuesday; T
|
||||||
e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T
|
e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T
|
||||||
F week-of-month number 3
|
F week-of-month number 3
|
||||||
|
|
||||||
a am-pm-of-day text PM
|
a am-pm-of-day text PM
|
||||||
h clock-hour-of-am-pm (1-12) number 12
|
h clock-hour-of-am-pm (1-12) number 12
|
||||||
K hour-of-am-pm (0-11) number 0
|
K hour-of-am-pm (0-11) number 0
|
||||||
k clock-hour-of-am-pm (1-24) number 0
|
k clock-hour-of-am-pm (1-24) number 0
|
||||||
|
|
||||||
H hour-of-day (0-23) number 0
|
H hour-of-day (0-23) number 0
|
||||||
m minute-of-hour number 30
|
m minute-of-hour number 30
|
||||||
s second-of-minute number 55
|
s second-of-minute number 55
|
||||||
|
@ -697,16 +755,16 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
A milli-of-day number 1234
|
A milli-of-day number 1234
|
||||||
n nano-of-second number 987654321
|
n nano-of-second number 987654321
|
||||||
N nano-of-day number 1234000000
|
N nano-of-day number 1234000000
|
||||||
|
|
||||||
V time-zone ID zone-id America/Los_Angeles; Z; -08:30
|
V time-zone ID zone-id America/Los_Angeles; Z; -08:30
|
||||||
z time-zone name zone-name Pacific Standard Time; PST
|
z time-zone name zone-name Pacific Standard Time; PST
|
||||||
O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00;
|
O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00;
|
||||||
X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15;
|
X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15;
|
||||||
x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15;
|
x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15;
|
||||||
Z zone-offset offset-Z +0000; -0800; -08:00;
|
Z zone-offset offset-Z +0000; -0800; -08:00;
|
||||||
|
|
||||||
p pad next pad modifier 1
|
p pad next pad modifier 1
|
||||||
|
|
||||||
' escape for text delimiter
|
' escape for text delimiter
|
||||||
'' single quote literal '
|
'' single quote literal '
|
||||||
[ optional section start
|
[ optional section start
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package ctbrec.ui.sites.chaturbate;
|
package ctbrec.ui.sites.chaturbate;
|
||||||
|
|
||||||
|
import ctbrec.Config;
|
||||||
import ctbrec.sites.chaturbate.Chaturbate;
|
import ctbrec.sites.chaturbate.Chaturbate;
|
||||||
import ctbrec.ui.sites.AbstractTabProvider;
|
import ctbrec.ui.sites.AbstractTabProvider;
|
||||||
import ctbrec.ui.tabs.PaginatedScheduledService;
|
import ctbrec.ui.tabs.PaginatedScheduledService;
|
||||||
|
@ -14,32 +15,47 @@ public class ChaturbateTabProvider extends AbstractTabProvider {
|
||||||
|
|
||||||
private final String apiUrl;
|
private final String apiUrl;
|
||||||
private final ChaturbateFollowedTab followedTab;
|
private final ChaturbateFollowedTab followedTab;
|
||||||
|
private final boolean regionNAEnabled; // Store the setting
|
||||||
|
|
||||||
public ChaturbateTabProvider(Chaturbate chaturbate) {
|
public ChaturbateTabProvider(Chaturbate chaturbate) {
|
||||||
super(chaturbate);
|
super(chaturbate);
|
||||||
apiUrl = site.getBaseUrl() + "/api/ts";
|
apiUrl = site.getBaseUrl() + "/api/ts";
|
||||||
this.followedTab = new ChaturbateFollowedTab("Followed", apiUrl + "/roomlist/room-list/?enable_recommendations=false&follow=true", chaturbate);
|
regionNAEnabled = Config.getInstance().isFilterNAcamsOnlyEnabled();
|
||||||
|
this.followedTab = new ChaturbateFollowedTab("Followed", buildUrl("/roomlist/room-list/?enable_recommendations=false&follow=true"), chaturbate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<Tab> getSiteTabs(Scene scene) {
|
protected List<Tab> getSiteTabs(Scene scene) {
|
||||||
List<Tab> tabs = new ArrayList<>();
|
List<Tab> tabs = new ArrayList<>();
|
||||||
tabs.add(createTab("Featured", apiUrl + "/roomlist/room-list/?enable_recommendations=false"));
|
tabs.add(createTab("Featured", buildUrl("/roomlist/room-list/?enable_recommendations=false")));
|
||||||
tabs.add(createTab("Female", apiUrl + "/roomlist/room-list/?enable_recommendations=false&genders=f"));
|
tabs.add(createTab("Female", buildUrl("/roomlist/room-list/?enable_recommendations=false&genders=f")));
|
||||||
tabs.add(createTab("New Female", apiUrl + "/roomlist/room-list/?enable_recommendations=false&genders=f&new_cams=true"));
|
tabs.add(createTab("New Female", buildUrl("/roomlist/room-list/?enable_recommendations=false&genders=f&new_cams=true")));
|
||||||
tabs.add(createTab("Male", apiUrl + "/roomlist/room-list/?enable_recommendations=false&genders=m"));
|
tabs.add(createTab("Milf", buildUrl("/roomlist/room-list/?enable_recommendations=false&hashtags=milf")));
|
||||||
tabs.add(createTab("New Male", apiUrl + "/roomlist/room-list/?enable_recommendations=false&genders=m&new_cams=true"));
|
tabs.add(createTab("Teen", buildUrl("/roomlist/room-list/?enable_recommendations=false&hashtags=teen")));
|
||||||
tabs.add(createTab("Couples", apiUrl + "/roomlist/room-list/?enable_recommendations=false&genders=c"));
|
tabs.add(createTab("Creampie", buildUrl("/roomlist/room-list/?enable_recommendations=false&hashtags=creampie")));
|
||||||
tabs.add(createTab("Trans", apiUrl + "/roomlist/room-list/?enable_recommendations=false&genders=t"));
|
tabs.add(createTab("BBW", buildUrl("/roomlist/room-list/?enable_recommendations=false&hashtags=bbw")));
|
||||||
tabs.add(createTab("Private", apiUrl + "/roomlist/room-list/?enable_recommendations=false&private=true"));
|
tabs.add(createTab("Chubby", buildUrl("/roomlist/room-list/?enable_recommendations=false&hashtags=chubby")));
|
||||||
tabs.add(createTab("Hidden", apiUrl + "/roomlist/room-list/?enable_recommendations=false&hidden=true"));
|
tabs.add(createTab("Pregnant", buildUrl("/roomlist/room-list/?enable_recommendations=false&hashtags=pregnant")));
|
||||||
tabs.add(createTab("Gaming", apiUrl + "/roomlist/room-list/?enable_recommendations=false&gaming=true"));
|
tabs.add(createTab("Male", buildUrl("/roomlist/room-list/?enable_recommendations=false&genders=m")));
|
||||||
|
tabs.add(createTab("New Male", buildUrl("/roomlist/room-list/?enable_recommendations=false&genders=m&new_cams=true")));
|
||||||
|
tabs.add(createTab("Couples", buildUrl("/roomlist/room-list/?enable_recommendations=false&genders=c")));
|
||||||
|
tabs.add(createTab("Trans", buildUrl("/roomlist/room-list/?enable_recommendations=false&genders=t")));
|
||||||
|
tabs.add(createTab("N.American Cams", buildUrl("/roomlist/room-list/?enable_recommendations=false®ions=NA")));
|
||||||
|
tabs.add(createTab("6TPM private", buildUrl("/roomlist/room-list/?enable_recommendations=false&private_prices=6")));
|
||||||
|
tabs.add(createTab("Private", buildUrl("/roomlist/room-list/?enable_recommendations=false&private=true")));
|
||||||
|
tabs.add(createTab("Hidden", buildUrl("/roomlist/room-list/?enable_recommendations=false&hidden=true")));
|
||||||
|
tabs.add(createTab("Gaming", buildUrl("/roomlist/room-list/?enable_recommendations=false&gaming=true")));
|
||||||
|
|
||||||
followedTab.setScene(scene);
|
followedTab.setScene(scene);
|
||||||
followedTab.setRecorder(recorder);
|
followedTab.setRecorder(recorder);
|
||||||
followedTab.setImageAspectRatio(9.0 / 16.0);
|
followedTab.setImageAspectRatio(9.0 / 16.0);
|
||||||
tabs.add(followedTab);
|
tabs.add(followedTab);
|
||||||
|
|
||||||
|
//tabs.add(createApiTab("Top Rated", buildUrl("/discover/carousels/top-rated/")));
|
||||||
|
//tabs.add(createApiTab("Trending", buildUrl("/discover/carousels/trending/")));
|
||||||
tabs.add(createApiTab("Top Rated", apiUrl + "/discover/carousels/top-rated/"));
|
tabs.add(createApiTab("Top Rated", apiUrl + "/discover/carousels/top-rated/"));
|
||||||
tabs.add(createApiTab("Trending", apiUrl + "/discover/carousels/trending/"));
|
tabs.add(createApiTab("Trending", apiUrl + "/discover/carousels/trending/"));
|
||||||
|
|
||||||
return tabs;
|
return tabs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,4 +80,29 @@ public class ChaturbateTabProvider extends AbstractTabProvider {
|
||||||
var updateService = new ChaturbateApiUpdateService(apiUrl, (Chaturbate) site);
|
var updateService = new ChaturbateApiUpdateService(apiUrl, (Chaturbate) site);
|
||||||
return createTab(title, updateService);
|
return createTab(title, updateService);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private String buildUrl(String endpoint) {
|
||||||
|
boolean filterNA = Config.getInstance().getSettings().filterNAcamsOnly; // Always check latest setting
|
||||||
|
|
||||||
|
// Do NOT modify "N.American Cams" - it should always have ®ions=NA
|
||||||
|
if (endpoint.contains("®ions=NA")) {
|
||||||
|
return apiUrl + endpoint; // Keep it unchanged
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure Top Rated & Trending use ? instead of &
|
||||||
|
if (filterNA && endpoint.contains("discover/carousels")) {
|
||||||
|
endpoint += "?regions=NA"; // Use ? instead of &
|
||||||
|
}
|
||||||
|
// For all other tabs (except N.American Cams), append ®ions=NA if enabled
|
||||||
|
else if (filterNA) {
|
||||||
|
endpoint += "®ions=NA";
|
||||||
|
}
|
||||||
|
|
||||||
|
String url = apiUrl + endpoint;
|
||||||
|
System.out.println("Building URL: " + url); // Debugging output
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -773,6 +773,9 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
||||||
popoverTreeList.setRecorder(recorder);
|
popoverTreeList.setRecorder(recorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PaginatedScheduledService getUpdateService() {
|
||||||
|
return updateService;
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public void selected() {
|
public void selected() {
|
||||||
grid.getChildren().removeAll(noResultsFound, errorLabel);
|
grid.getChildren().removeAll(noResultsFound, errorLabel);
|
||||||
|
|
|
@ -162,6 +162,9 @@ public class Config {
|
||||||
String json = new String(fileContent, UTF_8).trim();
|
String json = new String(fileContent, UTF_8).trim();
|
||||||
json = migrateJson(json);
|
json = migrateJson(json);
|
||||||
settings = Objects.requireNonNull(mapper.readValue(json, Settings.class));
|
settings = Objects.requireNonNull(mapper.readValue(json, Settings.class));
|
||||||
|
JSONObject jsonObject = new JSONObject(json);
|
||||||
|
settings.filterNAcamsOnly = jsonObject.optBoolean("filterNAcamsOnly", false);
|
||||||
|
|
||||||
settings.httpTimeout = Math.max(settings.httpTimeout, 10_000);
|
settings.httpTimeout = Math.max(settings.httpTimeout, 10_000);
|
||||||
if (settings.recordingsDir.endsWith("/")) {
|
if (settings.recordingsDir.endsWith("/")) {
|
||||||
settings.recordingsDir = settings.recordingsDir.substring(0, settings.recordingsDir.length() - 1);
|
settings.recordingsDir = settings.recordingsDir.substring(0, settings.recordingsDir.length() - 1);
|
||||||
|
@ -221,11 +224,11 @@ public class Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void migrateTo5_3_2(JSONObject json) {
|
private void migrateTo5_3_2(JSONObject json) {
|
||||||
if (json.has("chaturbateUseFlaresolverr") && json.has("flaresolverr")) {
|
if (json.has("chaturbateUseFlaresolverr") && json.has("flaresolverr")) {
|
||||||
var fsr = json.getJSONObject("flaresolverr");
|
var fsr = json.getJSONObject("flaresolverr");
|
||||||
|
|
||||||
if (!fsr.has("useForDomains") && json.getBoolean("chaturbateUseFlaresolverr")) {
|
if (!fsr.has("useForDomains") && json.getBoolean("chaturbateUseFlaresolverr")) {
|
||||||
fsr.put("useForDomains", new JSONArray().put("chaturbate.com"));
|
fsr.put("useForDomains", new JSONArray().put("chaturbate.com"));
|
||||||
}
|
}
|
||||||
|
@ -257,11 +260,13 @@ public class Config {
|
||||||
if (savingDisabled) {
|
if (savingDisabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String json = mapper.writeValueAsString(settings);
|
JSONObject jsonObject = new JSONObject(mapper.writeValueAsString(settings));
|
||||||
|
jsonObject.put("filterNAcamsOnly", settings.filterNAcamsOnly);
|
||||||
|
String jsonString = jsonObject.toString();
|
||||||
File configFile = new File(configDir, filename);
|
File configFile = new File(configDir, filename);
|
||||||
log.debug("Saving config to {}", configFile.getAbsolutePath());
|
log.debug("Saving config to {}", configFile.getAbsolutePath());
|
||||||
Files.createDirectories(configDir.toPath());
|
Files.createDirectories(configDir.toPath());
|
||||||
Files.writeString(configFile.toPath(), json, CREATE, WRITE, TRUNCATE_EXISTING);
|
Files.writeString(configFile.toPath(), jsonString, CREATE, WRITE, TRUNCATE_EXISTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isServerMode() {
|
public static boolean isServerMode() {
|
||||||
|
@ -358,4 +363,8 @@ public class Config {
|
||||||
List<String> ignored = Config.getInstance().getSettings().ignoredModels;
|
List<String> ignored = Config.getInstance().getSettings().ignoredModels;
|
||||||
return ignored.contains(model.getUrl());
|
return ignored.contains(model.getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isFilterNAcamsOnlyEnabled() {
|
||||||
|
return settings.filterNAcamsOnly;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,7 @@ public class Settings {
|
||||||
public String mfcPassword = "";
|
public String mfcPassword = "";
|
||||||
public String mfcUsername = "";
|
public String mfcUsername = "";
|
||||||
public boolean minimizeToTray = false;
|
public boolean minimizeToTray = false;
|
||||||
|
public boolean filterNAcamsOnly = false;
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public int minimumLengthInSeconds = 0;
|
public int minimumLengthInSeconds = 0;
|
||||||
public long minimumSpaceLeftInBytes = 0;
|
public long minimumSpaceLeftInBytes = 0;
|
||||||
|
|
1070
docs/index.html
1070
docs/index.html
File diff suppressed because it is too large
Load Diff
|
@ -23,6 +23,8 @@
|
||||||
<jackson.version>2.15.1</jackson.version>
|
<jackson.version>2.15.1</jackson.version>
|
||||||
<org.mapstruct.version>1.5.3.Final</org.mapstruct.version>
|
<org.mapstruct.version>1.5.3.Final</org.mapstruct.version>
|
||||||
<lombok.version>1.18.30</lombok.version>
|
<lombok.version>1.18.30</lombok.version>
|
||||||
|
<lombok.version>1.18.30</lombok.version>
|
||||||
|
<buildNumber>SNAPSHOT</buildNumber> <!-- Default value if none is provided -->
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -44,6 +46,27 @@
|
||||||
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>buildnumber-maven-plugin</artifactId>
|
||||||
|
<version>1.4</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>validate</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>create</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<doCheck>true</doCheck>
|
||||||
|
<doUpdate>false</doUpdate>
|
||||||
|
<providerImplementations>
|
||||||
|
<svn>javasvn</svn>
|
||||||
|
<git>jgit</git>
|
||||||
|
</providerImplementations>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</pluginManagement>
|
</pluginManagement>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {}
|
||||||
|
}
|
Loading…
Reference in New Issue