diff --git a/.bh.ps1 b/.bh.ps1
index 69ac7679..f2d1ed99 100644
--- a/.bh.ps1
+++ b/.bh.ps1
@@ -1,17 +1,19 @@
param(
[string]$HostName = "127.0.0.1",
[int]$Port = 7860,
- [int]$Timeout = 60
+ [int]$Timeout = 90
)
+
for ($i = 1; $i -le $Timeout; $i++) {
try {
$tcp = [System.Net.Sockets.TcpClient]::new()
$tcp.Connect($HostName, $Port)
$tcp.Close()
Start-Process "http://${HostName}:$Port/"
- break
+ exit 0
}
catch {
Start-Sleep -Seconds 1
}
-}
\ No newline at end of file
+}
+exit 0
\ No newline at end of file
diff --git a/ebook2audiobook.cmd b/ebook2audiobook.cmd
index 03f7e8a4..c83249ef 100755
--- a/ebook2audiobook.cmd
+++ b/ebook2audiobook.cmd
@@ -6,10 +6,14 @@ set "ARGS=%*"
set "NATIVE=native"
set "FULL_DOCKER=full_docker"
set "SCRIPT_MODE=%NATIVE%"
-set "APP_NAME=ebook2audiobook"
set "SCRIPT_DIR=%~dp0"
-set "RUN_SCRIPT=ebook2audiobook.cmd"
-set "ICON_PATH=%SCRIPT_DIR%tools\icons\windows\appIcon.ico"
+if "%SCRIPT_DIR:~-1%"=="\" set "SCRIPT_DIR=%SCRIPT_DIR:~0,-1%"
+set "APP_NAME=ebook2audiobook"
+set /p APP_VERSION=<"%SCRIPT_DIR%\VERSION.txt"
+set "APP_FILE=%APP_NAME%.cmd"
+set "TEST_HOST=127.0.0.1"
+set "TEST_PORT=7860"
+set "ICON_PATH=%SCRIPT_DIR%\tools\icons\windows\appIcon.ico"
set "STARTMENU_DIR=%APPDATA%\Microsoft\Windows\Start Menu\Programs\%APP_NAME%"
set "STARTMENU_LNK=%STARTMENU_DIR%\%APP_NAME%.lnk"
set "DESKTOP_LNK=%USERPROFILE%\Desktop\%APP_NAME%.lnk"
@@ -35,6 +39,7 @@ set "TESSDATA_PREFIX=%SCRIPT_DIR%\models\tessdata"
set "NODE_PATH=%SCOOP_HOME%\apps\nodejs\current"
set "PATH=%SCOOP_SHIMS%;%SCOOP_APPS%;%CONDA_PATH%;%NODE_PATH%;%PATH%" 2>&1 >nul
set "INSTALLED_LOG=%SCRIPT_DIR%\.installed"
+set "UNINSTALLER=%SCRIPT_DIR%\uninstall.cmd"
set "HELP_FOUND=%ARGS:--help=%"
set "HEADLESS_FOUND=%ARGS:--headless=%"
@@ -253,13 +258,22 @@ goto :dispatch
exit /b
:make_shortcut
+reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\%APP_NAME%" /v "DisplayName" /d "%APP_NAME%" /f >nul 2>&1
+reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\%APP_NAME%" /v "DisplayVersion" /d "%APP_VERSION%" /f >nul 2>&1
+reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\%APP_NAME%" /v "Publisher" /d "ebook2audiobook Team" /f >nul 2>&1
+reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\%APP_NAME%" /v "InstallLocation" /d "%SCRIPT_DIR%" /f >nul 2>&1
+reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\%APP_NAME%" /v "UninstallString" /d "\"%UNINSTALLER%\"" /f >nul 2>&1
+reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\%APP_NAME%" /v "DisplayIcon" /d "%ICON_PATH%" /f >nul 2>&1
+reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\%APP_NAME%" /v "NoModify" /t REG_DWORD /d 1 /f >nul 2>&1
+reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\%APP_NAME%" /v "NoRepair" /t REG_DWORD /d 1 /f >nul 2>&1
powershell -NoLogo -NoProfile -Command ^
- "$s=(New-Object -ComObject WScript.Shell).CreateShortcut('%~1');" ^
- "$s.TargetPath='cmd.exe';" ^
- "$s.Arguments='/k cd ""%SCRIPT_DIR%"" && %RUN_SCRIPT%';" ^
- "$s.WorkingDirectory='%SCRIPT_DIR%';" ^
- "$s.IconLocation='%ICON_PATH%';" ^
- "$s.Save()"
+ "$s = New-Object -ComObject WScript.Shell; " ^
+ "$shortcut = $s.CreateShortcut('%~1'); " ^
+ "$shortcut.TargetPath = 'cmd.exe'; " ^
+ "$shortcut.Arguments = '/k \"cd /d \"%SCRIPT_DIR%\" && \"%APP_FILE%\"\"'; " ^
+ "$shortcut.WorkingDirectory = '%SCRIPT_DIR%'; " ^
+ "$shortcut.IconLocation = '%ICON_PATH%'; " ^
+ "$shortcut.Save()"
exit /b
:build_gui
@@ -269,7 +283,7 @@ if not "%HEADLESS_FOUND%"=="%ARGS%" (
call :make_shortcut "%STARTMENU_LNK%"
call :make_shortcut "%DESKTOP_LNK%"
)
- start "E2A" powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File "%~dp0.bh.ps1"
+ start "E2A" powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File "%~dp0.bh.ps1" -HostName "%TEST_HOST%" -Port %TEST_PORT%
)
exit /b
diff --git a/ebook2audiobook.sh b/ebook2audiobook.sh
index 35b84ead..c6ca8266 100755
--- a/ebook2audiobook.sh
+++ b/ebook2audiobook.sh
@@ -49,11 +49,13 @@ NATIVE="native"
FULL_DOCKER="full_docker"
SCRIPT_MODE="$NATIVE"
APP_NAME="ebook2audiobook"
+APP_VERSION=$(<"$SCRIPT_DIR/VERSION.txt")
WGET=$(which wget 2>/dev/null)
REQUIRED_PROGRAMS=("curl" "pkg-config" "calibre" "ffmpeg" "nodejs" "espeak-ng" "rust" "sox" "tesseract")
PYTHON_ENV="python_env"
CURRENT_ENV=""
INSTALLED_LOG="$SCRIPT_DIR/.installed"
+UNINSTALLER="$SCRIPT_DIR/uninstall.sh"
if [[ "$OSTYPE" != "linux"* && "$OSTYPE" != "darwin"* ]]; then
echo "Error: OS $OSTYPE unsupported."
@@ -637,4 +639,6 @@ EOF
fi
fi
+exit 0
+exit 0
exit 0
\ No newline at end of file
diff --git a/lib/functions.py b/lib/functions.py
index be85f00b..6ef1c2b0 100644
--- a/lib/functions.py
+++ b/lib/functions.py
@@ -2418,7 +2418,7 @@ def build_interface(args:dict)->gr.Blocks:
is_gui_process = args['is_gui_process']
is_gui_shared = args['share']
title = 'Ebook2Audiobook'
- gr_glass_mask_msg = 'Initialization, please wait...'
+ gr_glassmask_msg = 'Initialization, please wait...'
ebook_src = None
language_options = [
(
@@ -2518,6 +2518,8 @@ def build_interface(args:dict)->gr.Blocks:
justify-content: center !important;
font-size: 1.2rem !important;
color: #ffffff !important;
+ text-align: center !important;
+ border: none !important;
opacity: 1;
pointer-events: all !important;
}
@@ -3046,7 +3048,7 @@ def build_interface(args:dict)->gr.Blocks:
gr_confirm_blocks_no_btn = gr.Button(elem_id='gr_confirm_blocks_no_btn', elem_classes=['hide-elem'], value='', variant='secondary', visible=True, scale=0, min_width=30)
gr_modal = gr.HTML(visible=False)
- gr_glass_mask = gr.HTML(gr_glass_mask_msg, elem_id='gr_glass_mask', elem_classes=['gr-glass-mask'])
+ gr_glassmask = gr.HTML(gr_glassmask_msg, elem_id='gr_glassmask', elem_classes=['gr-glass-mask'])
gr_confirm_deletion_field_hidden = gr.Textbox(elem_id='confirm_hidden', visible=False)
gr_confirm_deletion_yes_btn = gr.Button(elem_id='gr_confirm_deletion_yes_btn', elem_classes=['hide-elem'], value='', variant='secondary', visible=True, scale=0, size='sm', min_width=0)
gr_confirm_deletion_no_btn = gr.Button(elem_id='gr_confirm_deletion_no_btn', elem_classes=['hide-elem'], value='', variant='secondary', visible=True, scale=0, size='sm', min_width=0)
@@ -3246,8 +3248,8 @@ def build_interface(args:dict)->gr.Blocks:
alert_exception(error, id)
return gr.update(value=0), gr.update(value=None), gr.update(value=None)
- def update_gr_glass_mask(str:str=gr_glass_mask_msg, attr:list=['gr-glass-mask'])->dict:
- return gr.update(value=str, elem_id='gr_glass_mask', elem_classes=attr)
+ def update_gr_glassmask(str:str=gr_glassmask_msg, attr:list=['gr-glass-mask'])->dict:
+ return gr.update(value=str, elem_id='gr_glassmask', elem_classes=attr)
def change_convert_btn(upload_file:str|None=None, upload_file_mode:str|None=None, custom_model_file:str|None=None, session:DictProxy=None)->dict:
try:
@@ -3941,7 +3943,7 @@ def build_interface(args:dict)->gr.Blocks:
session['status'] = None
if not context_tracker.start_session(session['id']):
error = "Your session is already active.
If it's not the case please close your browser and relaunch it."
- return gr.update(), gr.update(), gr.update(value=''), update_gr_glass_mask(str=error)
+ return gr.update(), gr.update(), gr.update(value=''), update_gr_glassmask(str=error)
else:
active_sessions.add(req.session_hash)
session[req.session_hash] = req.session_hash
@@ -4358,7 +4360,7 @@ def build_interface(args:dict)->gr.Blocks:
gr_restore_session.change(
fn=change_gr_restore_session,
inputs=[gr_restore_session, gr_state_update],
- outputs=[gr_save_session, gr_state_update, gr_session, gr_glass_mask]
+ outputs=[gr_save_session, gr_state_update, gr_session, gr_glassmask]
).then(
fn=restore_interface,
inputs=[gr_session],
@@ -4374,9 +4376,9 @@ def build_interface(args:dict)->gr.Blocks:
gr_group_audiobook_list, gr_audiobook_player, gr_timer
]
).then(
- fn=lambda session: update_gr_glass_mask(attr=['gr-glass-mask', 'hide']) if session else gr.update(),
+ fn=lambda session: update_gr_glassmask(attr=['gr-glass-mask', 'hide']) if session else gr.update(),
inputs=[gr_session],
- outputs=[gr_glass_mask]
+ outputs=[gr_glassmask]
).then(
fn=None,
inputs=None,
@@ -4428,6 +4430,8 @@ def build_interface(args:dict)->gr.Blocks:
js=r'''
()=>{
try{
+ const bc = new BroadcastChannel("E2A-channel");
+ const tab_id = crypto.randomUUID();
let gr_root = (window.gradioApp && window.gradioApp()) || document;
let gr_checkboxes;
let gr_radios;
@@ -4438,9 +4442,10 @@ def build_interface(args:dict)->gr.Blocks:
let gr_playback_time;
let gr_progress;
let gr_voice_play;
+ let tabs_opened = false;
let init_elements_timeout;
let init_audiobook_player_timeout;
- let audioFilter = "";
+ let audio_filter = "";
let cues = [];
if(typeof window.onElementAvailable !== "function"){
window.onElementAvailable = (selector, callback, { root = (window.gradioApp && window.gradioApp()) || document, once = false } = {})=> {
@@ -4672,7 +4677,7 @@ def build_interface(args:dict)->gr.Blocks:
}
gr_audiobook_player.addEventListener("loadeddata", ()=>{
gr_audiobook_player.style.transition = "filter 1s ease";
- gr_audiobook_player.style.filter = audioFilter;
+ gr_audiobook_player.style.filter = audio_filter;
gr_audiobook_player.currentTime = parseFloat(window.session_storage.playback_time);
gr_audiobook_player.volume = window.session_storage.playback_volume;
});
@@ -4701,16 +4706,16 @@ def build_interface(args:dict)->gr.Blocks:
let osTheme;
if(theme){
if(theme == "dark"){
- audioFilter = "invert(1) hue-rotate(180deg)";
+ audio_filter = "invert(1) hue-rotate(180deg)";
}
}else{
osTheme = window.matchMedia?.("(prefers-color-scheme: dark)").matches;
if(osTheme){
- audioFilter = "invert(1) hue-rotate(180deg)";
+ audio_filter = "invert(1) hue-rotate(180deg)";
}
}
gr_audiobook_player.style.transition = "filter 1s ease";
- gr_audiobook_player.style.filter = audioFilter;
+ gr_audiobook_player.style.filter = audio_filter;
gr_audiobook_player.volume = window.session_storage.playback_volume;
return true;
}
@@ -4841,7 +4846,40 @@ def build_interface(args:dict)->gr.Blocks:
return [s.slice(0, idx).trim(), s.slice(idx + 1).trim()];
}
}
+ if(typeof(show_glassmask) !== "function"){
+ function show_glassmask(msg){
+ let glassmask = document.querySelector("#gr_glassmask");
+ if(!glassmask){
+ glassmask = document.createElement("div");
+ glassmask.id = "gr_glassmask";
+ document.body.appendChild(glassmask);
+ }
+ glassmask.className = "gr-glass-mask";
+ glassmask.innerHTML = `${msg}`;
+ }
+ }
//////////////////////
+ bc.onmessage = (event)=>{
+ try{
+ const msg = event.data;
+ if(!msg || msg.senderId === tab_id){
+ return;
+ }
+ switch (msg.type){
+ case "check-existing":
+ bc.postMessage({ type: "already-open", senderId: tab_id });
+ break;
+ case "already-open":
+ tabs_opened = true;
+ break;
+ case "new-tab-opened":
+ show_glassmask(msg.text);
+ break;
+ }
+ }catch(e){
+ console.warn("bc.onmessage error:", e);
+ }
+ };
window.addEventListener("beforeunload", ()=>{
try{
const newStorage = JSON.parse(localStorage.getItem("data") || "{}");
@@ -4859,7 +4897,7 @@ def build_interface(args:dict)->gr.Blocks:
const currentStorage = localStorage.getItem("data");
if(currentStorage){
window.session_storage = JSON.parse(currentStorage);
- window.session_storage.tab_id = "tab-" + performance.now().toString(36) + "-" + Math.random().toString(36).substring(2, 10);
+ window.session_storage.tab_id = tab_id;
if(window.session_storage.playback_volume === 0){
window.session_storage.playback_volume = 1.0;
}
@@ -4874,6 +4912,20 @@ def build_interface(args:dict)->gr.Blocks:
window.onElementAvailable("#gr_audiobook_player audio", (el)=>{
window.init_audiobook_player();
}, {once: false});
+ try{
+ bc.postMessage({ type: "check-existing", senderId: tab_id });
+ setTimeout(()=>{
+ if(tabs_opened){
+ bc.postMessage({
+ type: "new-tab-opened",
+ text: "Session expired.
You can close this window",
+ senderId: tab_id
+ });
+ }
+ }, 250);
+ }catch(e){
+ console.warn("bc.postMessage error:", e);
+ }
return window.session_storage;
}catch(e){
console.warn("gr_raed_data js error:", e);
diff --git a/lib/models.py b/lib/models.py
index 42b75d3a..7062d254 100644
--- a/lib/models.py
+++ b/lib/models.py
@@ -148,7 +148,7 @@ default_engine_settings = {
"samplerate": 16000,
"files": ['config.json', 'model_file.pth'],
"voices": {"Machinella-5": "female-en-5", "ElectroMale-2": "male-en-2", 'Machinella-4': 'female-pt-4\n', 'ElectroMale-3': 'male-pt-3\n'},
- "rating": {"VRAM": 0, "CPU": 5, "RAM": 1, "Realism": 2}
+ "rating": {"VRAM": 1, "CPU": 5, "RAM": 1, "Realism": 2}
}
}
models = {