Skip to content

Commit 5e1bfed

Browse files
committed
fix: bump version to 1.5.0, major bug fix release
1 parent f2649da commit 5e1bfed

23 files changed

Lines changed: 347 additions & 145 deletions

File tree

.github/workflows/release.yml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@ jobs:
2323
- platform: 'windows-latest'
2424
args: '--target aarch64-pc-windows-msvc'
2525

26-
# 4. Linux (Ubuntu)
27-
- platform: 'ubuntu-24.04'
26+
# 4. Linux (Ubuntu Intel / AMD)
27+
- platform: 'ubuntu-latest'
28+
args: ''
29+
# 5. Linux ARM (Ubuntu)
30+
- platform: 'ubuntu-24.04-arm'
2831
args: ''
2932

3033
runs-on: ${{ matrix.platform }}
@@ -34,10 +37,10 @@ jobs:
3437

3538
# 1. Install Linux Dependencies (Only runs on Ubuntu)
3639
- name: Install dependencies (Ubuntu only)
37-
if: matrix.platform == 'ubuntu-24.04'
40+
if: startsWith(matrix.platform, 'ubuntu')
3841
run: |
3942
sudo apt-get update
40-
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
43+
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf xdg-utils
4144
4245
# 2. Setup Java & Build Backend
4346
- name: Setup Java
@@ -69,6 +72,8 @@ jobs:
6972
working-directory: ./app/frontend
7073
run: npm install
7174

75+
# Note: We don't need to add a cross-compile target for Linux ARM
76+
# because it will compile natively directly on the ubuntu-24.04-arm runner!
7277
- name: Install Rust
7378
uses: dtolnay/rust-toolchain@stable
7479
with:
@@ -82,7 +87,7 @@ jobs:
8287
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
8388
with:
8489
projectPath: ./app/frontend
85-
tagName: ${{ github.ref_name }} # e.g., v1.3.0
90+
tagName: ${{ github.ref_name }}
8691
releaseName: 'SRT Translator & Validator ${{ github.ref_name }}'
8792
releaseBody: 'A new update is available! Please see the GitHub release page for the full changelog and details.'
8893
releaseDraft: true

Example Config Prompt Template.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
{{Basic Latin}} {{Latin Supplement}} {{Telugu}}
55
{{TV show}} {{Psych}} {{2006}} {{, S01E01}} {{, (Title)}} {{Shawn Spencer}} {{}} {{}}
66

7-
You are a hyper-vigilant subtitle translator and formatter. Your task is to translate an English .srt file into casual "Tenglish" (a mix of Telugu and English). Your primary directive is 100% accuracy in CONTENT MAPPING and SCRIPT & LANGUAGE RULES mentioned below. Failure to adhere to these rules is not an option.
7+
Your task is to translate an English .srt file into casual "Tenglish" (a mix of Telugu and English). Your primary directive is 100% accuracy in CONTENT MAPPING and SCRIPT & LANGUAGE RULES mentioned below. Failure to adhere to these rules is not an option.
88

99
**Goal:** Translate the attached English .srt file for the {{Enter movie or TV show}} {{Movie/TV Show Name}} ({{Release Year}}){{Season/Episode Number in the format , S01E01}}{{Episode Title in the format , (Title)}} into casual Telugu for a native Telugu speaker who is not fluent in English.
1010

README.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,24 @@
1212

1313
A comprehensive browser-based and desktop tool that leverages Large Language Models (LLMs) to translate SRT subtitle files and automatically validate the output for common errors. Built specifically to create high-quality, script-accurate subtitles using your existing LLM subscriptions (Gemini, ChatGPT, Claude, etc.) via [CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI).
1414

15-
Original TV Show in English | Output of translated SRT in Tenglish
15+
Input SRT in English | Output of translated SRT in Tenglish
1616
:-------------------------:|:-------------------------:
17-
![](./images/psych_english_translation.png) | ![](./images/psych_tenglish_translation.png)
17+
<img src="./images/psych_english_translation.png"> | <img src="./images/psych_tenglish_translation.png">
1818

1919
> [!NOTE]
2020
> Screenshots are taken from *Psych*, an American detective comedy-drama television series created by Steve Franks for USA Network.
2121
2222
## Motivation
2323

24-
My mom loves to watch movies and TV shows, but she isn't fluent in English. Properly translated subtitles are the perfect way for her to enjoy and understand the content. While Large Language Models (LLMs) are incredibly powerful and can translate subtitles in minutes, they often introduce subtle errors, such as:
24+
My mom loves to watch movies and TV shows, but she isn't fluent in English. Properly translated subtitles are the perfect way for her to enjoy and understand the content. When I set out to find a subtitle translator powered by mainstream LLMs, I hit several roadblocks.
25+
26+
Existing solutions either required expensive paid API keys, charged high per-token rates (I tested commercial options like [GPT Subtitler](https://gptsubtitler.com/), but the pricing was unsustainable for my regular usage), or completely lacked the ability to detect and automatically fix the subtle formatting errors LLMs often introduce. Furthermore, I wanted a way to leverage my existing Gemini subscription rather than paying separately for API usage—which this tool achieves via [CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI).
27+
28+
While Large Language Models are incredibly powerful and can translate subtitles in minutes, they often introduce subtle errors without strict oversight, such as:
2529

2630
* **Timestamp Drift:** The model may slightly alter timestamps, causing subtitles to appear too early or too late.
2731
* **Character "Hallucinations":** When translating for a specific language (like Telugu), the model might mistakenly insert characters from a similar-looking but incorrect script (like Devanagari, Tamil, or Kannada).
28-
* **Incomplete Translations:** Long subtitle files may be cut off mid-translation.
32+
* **Incomplete Translations:** Long subtitle files may be cut off mid-translation due to context limits.
2933
* **Formatting Errors:** Line breaks or subtitle numbering can sometimes be corrupted.
3034

3135
This tool automates the entire translation workflow, validates the output, and provides one-click fixes for common LLM errors—ensuring the subtitles are perfect.
@@ -146,11 +150,11 @@ Create or edit your `config.yaml` file.
146150

147151
For more information, please visit: https://help.router-for.me/configuration/basic.html or use the provided example `config.yaml`.
148152

153+
</details>
154+
149155
> [!IMPORTANT]
150156
> The `api-keys` value in `config.yaml` must match the API Key field in the web application. The key `dummy` is used by default if the field is left blank.
151157
152-
</details>
153-
154158
## Usage
155159

156160
### 1. Start CLIProxyAPI Server
@@ -255,7 +259,7 @@ When a configured template is imported:
255259
256260
**Example Non-Template Prompt:**
257261
```markdown
258-
You are a hyper-vigilant subtitle translator and formatter. Your task is to translate an English .srt file into casual "Tenglish" (a mix of Telugu and English). Your primary directive is 100% accuracy in CONTENT MAPPING and SCRIPT & LANGUAGE RULES mentioned below. Failure to adhere to these rules is not an option.
262+
Your task is to translate an English .srt file into casual "Tenglish" (a mix of Telugu and English). Your primary directive is 100% accuracy in CONTENT MAPPING and SCRIPT & LANGUAGE RULES mentioned below. Failure to adhere to these rules is not an option.
259263

260264
**Goal:** Translate the attached English .srt file for the TV show Psych (2006), S02E02, (65 Million Years Off) into casual Telugu for a native Telugu speaker who is not fluent in English.
261265

@@ -368,7 +372,7 @@ You can also add any custom Unicode range or character.
368372

369373
### Using Different Models
370374

371-
Edit the Model Name field to use other models. Since CLIProxyAPI supports OpenAI, Claude, and Gemini, you can input models like `gemini-3.1-pro-preview`, `gpt-5.4`, or `claude-opus-4-6`. Depending on the model selected, translation quality may vary:
375+
Edit the Model Name field to use other models. Since CLIProxyAPI supports OpenAI, Claude, and Gemini, you can input models like `gemini-3.1-pro-preview`, `gpt-5.5`, or `claude-opus-4-7`. Depending on the model selected, translation quality may vary:
372376
- `gemini-3-flash-preview`: Faster, cheaper, good for simple translations
373377
- `gemini-2.5-pro`: More accurate, better for complex translations
374378
- `gemini-3.1-pro-preview`: Latest model, best quality and reasoning

app/backend/pom.xml

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
<parent>
66
<groupId>org.springframework.boot</groupId>
77
<artifactId>spring-boot-starter-parent</artifactId>
8-
<version>3.5.12-SNAPSHOT</version>
8+
<version>3.5.13</version>
99
<relativePath/> <!-- lookup parent from repository -->
1010
</parent>
1111
<groupId>com.srttranslator</groupId>
1212
<artifactId>backend</artifactId>
1313
<version>0.0.1-SNAPSHOT</version>
1414
<name>srt-backend</name>
15-
<description>Spring Boot backend and CLIProxyAPI manager for the SRT Translator desktop app</description>
15+
<description>Spring Boot backend and CLI Proxy manager for the SRT Translator desktop app</description>
1616
<url/>
1717
<licenses>
1818
<license/>
@@ -84,25 +84,5 @@
8484
</plugin>
8585
</plugins>
8686
</build>
87-
<repositories>
88-
<repository>
89-
<id>spring-snapshots</id>
90-
<name>Spring Snapshots</name>
91-
<url>https://repo.spring.io/snapshot</url>
92-
<releases>
93-
<enabled>false</enabled>
94-
</releases>
95-
</repository>
96-
</repositories>
97-
<pluginRepositories>
98-
<pluginRepository>
99-
<id>spring-snapshots</id>
100-
<name>Spring Snapshots</name>
101-
<url>https://repo.spring.io/snapshot</url>
102-
<releases>
103-
<enabled>false</enabled>
104-
</releases>
105-
</pluginRepository>
106-
</pluginRepositories>
10787

108-
</project>
88+
</project>

app/backend/src/main/java/com/srttranslator/backend/controller/SettingsController.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ public Settings getSettings() {
2727
defaultSettings.setApiEndpoint("http://localhost:8317/v1/chat/completions");
2828
defaultSettings.setLiteModel("gemini-3-flash-preview");
2929
defaultSettings.setMainModel("gemini-3.1-pro-preview");
30-
defaultSettings.setCliCommandWindows("cli-proxy-api.exe --config \"%USERPROFILE%\\Downloads\\config.yaml\"");
31-
defaultSettings.setCliCommandMac("/opt/homebrew/opt/cliproxyapi/bin/cliproxyapi --config \"$HOME/Downloads/config.yaml\"");
32-
defaultSettings.setCliCommandLinux("cli-proxy-api --config \"$HOME/Downloads/config.yaml\"");
30+
defaultSettings.setCliCommandWindows("\"%USERPROFILE%\\Desktop\\cli-proxy-api\" --config \"%USERPROFILE%\\Desktop\\config.yaml\"");
31+
defaultSettings.setCliCommandMac("\"/opt/homebrew/opt/cliproxyapi/bin/cliproxyapi\" --config \"$HOME/Desktop/config.yaml\"");
32+
defaultSettings.setCliCommandLinux("\"$HOME/cliproxyapi/cli-proxy-api\" --config \"$HOME/Desktop/config.yaml\"");
3333
return repository.save(defaultSettings);
3434
});
3535
}
@@ -39,8 +39,8 @@ public Settings updateSettings(@RequestBody Settings updatedSettings) {
3939
updatedSettings.setId(1L); // Force ID 1 to maintain single row
4040
Settings saved = repository.save(updatedSettings);
4141

42-
// Restart the proxy immediately using the new commands
43-
cliProxyManagerService.restartProxy();
42+
// Stop the proxy immediately using the new commands
43+
cliProxyManagerService.stopProxy();
4444

4545
return saved;
4646
}

app/backend/src/main/java/com/srttranslator/backend/service/CliProxyManagerService.java

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
import org.slf4j.LoggerFactory;
88
import org.springframework.stereotype.Service;
99

10-
import java.io.IOException;
11-
1210
@Service
1311
public class CliProxyManagerService {
1412

@@ -23,49 +21,76 @@ public CliProxyManagerService(SettingsRepository settingsRepository) {
2321
// Removed @PostConstruct so it doesn't start automatically
2422
public void startProxy() {
2523
if (isProxyRunning()) {
26-
logger.info("CLIProxyAPI is already running.");
24+
logger.info("CLI Proxy is already running.");
2725
return;
2826
}
2927

3028
Settings settings = settingsRepository.findById(1L).orElseGet(() -> {
3129
Settings defaults = new Settings();
3230
// Restored the defaults you wanted
33-
defaults.setCliCommandWindows("cli-proxy-api.exe --config \"%USERPROFILE%\\Downloads\\config.yaml\"");
34-
defaults.setCliCommandMac("/opt/homebrew/opt/cliproxyapi/bin/cliproxyapi --config \"$HOME/Downloads/config.yaml\"");
35-
defaults.setCliCommandLinux("cli-proxy-api --config \"$HOME/Downloads/config.yaml\"");
31+
defaults.setCliCommandWindows("\"%USERPROFILE%\\Desktop\\cli-proxy-api\" --config \"%USERPROFILE%\\Desktop\\config.yaml\"");
32+
defaults.setCliCommandMac("\"/opt/homebrew/opt/cliproxyapi/bin/cliproxyapi\" --config \"$HOME/Desktop/config.yaml\"");
33+
defaults.setCliCommandLinux("\"$HOME/cliproxyapi/cli-proxy-api\" --config \"$HOME/Desktop/config.yaml\"");
3634
return defaults;
3735
});
3836

3937
String osName = System.getProperty("os.name").toLowerCase();
4038
ProcessBuilder builder;
4139

4240
if (osName.contains("win")) {
43-
builder = new ProcessBuilder("cmd.exe", "/c", settings.getCliCommandWindows());
41+
// Add "/s" and wrap the entire command string in an extra set of quotes
42+
builder = new ProcessBuilder("cmd.exe", "/s", "/c", "\"" + settings.getCliCommandWindows() + "\"");
4443
} else if (osName.contains("mac")) {
4544
// Add "exec " so the shell replaces itself with the proxy binary
4645
builder = new ProcessBuilder("sh", "-c", "exec " + settings.getCliCommandMac());
4746
} else if (osName.contains("nix") || osName.contains("nux") || osName.contains("aix")) {
4847
// Add "exec " here as well
4948
builder = new ProcessBuilder("sh", "-c", "exec " + settings.getCliCommandLinux());
5049
} else {
51-
logger.warn("Unsupported Operating System. Cannot start CLIProxyAPI.");
50+
logger.warn("Unsupported Operating System. Cannot start CLI proxy.");
5251
return;
5352
}
5453

5554
try {
56-
logger.info("Attempting to start CLIProxyAPI with command via shell...");
55+
logger.info("Attempting to start CLI Proxy with command via shell...");
5756
builder.redirectErrorStream(true);
5857
proxyProcess = builder.start();
59-
logger.info("CLIProxyAPI process spawned successfully.");
60-
} catch (IOException e) {
61-
logger.error("Failed to start CLIProxyAPI.", e);
58+
59+
// --- ADDED: Read the output stream to prevent OS hangs and see logs ---
60+
new Thread(() -> {
61+
try (java.io.BufferedReader reader = new java.io.BufferedReader(
62+
new java.io.InputStreamReader(proxyProcess.getInputStream()))) {
63+
String line;
64+
while ((line = reader.readLine()) != null) {
65+
logger.info("[CLI Proxy]: " + line);
66+
}
67+
} catch (Exception e) {
68+
logger.error("Error reading proxy output.", e);
69+
}
70+
}).start();
71+
// ----------------------------------------------------------------------
72+
73+
// --- ADDED: Wait a split second to see if the command instantly crashes ---
74+
Thread.sleep(500);
75+
76+
if (!proxyProcess.isAlive()) {
77+
logger.error("CLI Proxy crashed immediately! Exit code: " + proxyProcess.exitValue());
78+
proxyProcess = null; // Clear the dead process so the UI knows it's offline
79+
} else {
80+
logger.info("CLI Proxy process spawned successfully.");
81+
}
82+
// --------------------------------------------------------------------------
83+
84+
} catch (Exception e) { // Changed to Exception to also catch InterruptedException
85+
logger.error("Failed to start CLI Proxy.", e);
86+
proxyProcess = null;
6287
}
6388
}
6489

6590
@PreDestroy
6691
public void stopProxy() {
6792
if (isProxyRunning()) {
68-
logger.info("Application is shutting down. Terminating CLIProxyAPI...");
93+
logger.info("Application is shutting down. Terminating CLI Proxy...");
6994

7095
// Explicitly kill any child processes first (crucial for Windows cmd.exe wrapper)
7196
proxyProcess.descendants().forEach(ProcessHandle::destroy);
@@ -76,14 +101,14 @@ public void stopProxy() {
76101
try {
77102
Thread.sleep(1000);
78103
if (proxyProcess.isAlive()) {
79-
logger.warn("CLIProxyAPI did not terminate cleanly. Forcing shutdown...");
104+
logger.warn("CLI Proxy did not terminate cleanly. Forcing shutdown...");
80105
proxyProcess.descendants().forEach(ProcessHandle::destroyForcibly);
81106
proxyProcess.destroyForcibly();
82107
}
83108
} catch (InterruptedException e) {
84109
Thread.currentThread().interrupt();
85110
}
86-
logger.info("CLIProxyAPI terminated.");
111+
logger.info("CLI Proxy terminated.");
87112
}
88113
}
89114

app/frontend/index.html

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,19 @@
55
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<title>srt-translator</title>
8+
9+
<script>
10+
const isMac = navigator.userAgent.includes('Mac');
11+
const isWindows = navigator.userAgent.includes('Windows');
12+
const isLinux = !isMac && !isWindows;
13+
14+
if (isLinux) {
15+
document.documentElement.classList.add('linux-transparent');
16+
}
17+
</script>
818
</head>
919
<body>
1020
<div id="root"></div>
1121
<script type="module" src="/src/main.tsx"></script>
1222
</body>
13-
</html>
23+
</html>

app/frontend/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "srt-translator",
33
"private": true,
4-
"version": "1.4.0",
4+
"version": "1.5.0",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",
@@ -41,4 +41,4 @@
4141
"typescript-eslint": "^8.48.0",
4242
"vite": "^7.3.1"
4343
}
44-
}
44+
}

app/frontend/src-tauri/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ tauri-plugin-opener = "2"
2727
tauri-plugin-process = "2"
2828
tauri-plugin-dialog = "2"
2929
tauri-plugin-fs = "2"
30+
ureq = "3.3.0"
3031

3132
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
32-
tauri-plugin-updater = "2"
33+
tauri-plugin-updater = "2"

app/frontend/src-tauri/capabilities/default.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@
88
"permissions": [
99
"core:default",
1010
"core:window:allow-start-dragging",
11+
"core:window:allow-show",
12+
"core:window:allow-close",
13+
"core:window:allow-minimize",
14+
"core:window:allow-maximize",
15+
"core:window:allow-unmaximize",
16+
"core:window:allow-is-maximized",
17+
"core:window:allow-toggle-maximize",
1118
"opener:default",
1219
"fs:default",
1320
"fs:allow-write-text-file"

0 commit comments

Comments
 (0)