fix: keep tdata export working offline and under open_basedir
This commit is contained in:
@@ -103,7 +103,7 @@ class PluginSessionController extends Controller
|
|||||||
$python = config('coruna.tdata_python', base_path('channel-builder/.venv-tdata/bin/python'));
|
$python = config('coruna.tdata_python', base_path('channel-builder/.venv-tdata/bin/python'));
|
||||||
$script = config('coruna.tdata_script', base_path('channel-builder/tools/tglib_to_tdata.py'));
|
$script = config('coruna.tdata_script', base_path('channel-builder/tools/tglib_to_tdata.py'));
|
||||||
|
|
||||||
if (! is_file($python) || ! is_file($script)) {
|
if (! $this->conversionFileExists($python) || ! $this->conversionFileExists($script)) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'code' => 1,
|
'code' => 1,
|
||||||
'msg' => '转换环境未配置(缺少 Python 或脚本)',
|
'msg' => '转换环境未配置(缺少 Python 或脚本)',
|
||||||
@@ -122,10 +122,12 @@ class PluginSessionController extends Controller
|
|||||||
$exit = -1;
|
$exit = -1;
|
||||||
@exec($cmd, $output, $exit);
|
@exec($cmd, $output, $exit);
|
||||||
|
|
||||||
if ($exit !== 0 || ! is_file($zipPath)) {
|
if ($exit !== 0 || ! $this->conversionFileExists($zipPath)) {
|
||||||
$msg = implode("\n", $output) ?: "转换失败 (exit=$exit)";
|
$msg = implode("\n", $output) ?: "转换失败 (exit=$exit)";
|
||||||
@unlink($jsonPath);
|
@unlink($jsonPath);
|
||||||
if (is_file($zipPath)) @unlink($zipPath);
|
if ($this->conversionFileExists($zipPath)) {
|
||||||
|
@unlink($zipPath);
|
||||||
|
}
|
||||||
@rmdir($tmpDir);
|
@rmdir($tmpDir);
|
||||||
|
|
||||||
return response()->json(['code' => 1, 'msg' => $msg], 500);
|
return response()->json(['code' => 1, 'msg' => $msg], 500);
|
||||||
@@ -181,7 +183,7 @@ class PluginSessionController extends Controller
|
|||||||
$python = config('coruna.tdata_python', base_path('channel-builder/.venv-tdata/bin/python'));
|
$python = config('coruna.tdata_python', base_path('channel-builder/.venv-tdata/bin/python'));
|
||||||
$script = config('coruna.session_script', base_path('channel-builder/tools/tglib_to_session_files.py'));
|
$script = config('coruna.session_script', base_path('channel-builder/tools/tglib_to_session_files.py'));
|
||||||
|
|
||||||
if (! is_file($python) || ! is_file($script)) {
|
if (! $this->conversionFileExists($python) || ! $this->conversionFileExists($script)) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'code' => 1,
|
'code' => 1,
|
||||||
'msg' => '转换环境未配置(缺少 Python 或脚本)',
|
'msg' => '转换环境未配置(缺少 Python 或脚本)',
|
||||||
@@ -268,6 +270,19 @@ class PluginSessionController extends Controller
|
|||||||
}, $filename, ['Content-Type' => 'text/plain; charset=UTF-8']);
|
}, $filename, ['Content-Type' => 'text/plain; charset=UTF-8']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* is_file() throws when open_basedir blocks a symlink target; never
|
||||||
|
* leak that as an HTML 500 to the sessions page.
|
||||||
|
*/
|
||||||
|
private function conversionFileExists(string $path): bool
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return is_file($path);
|
||||||
|
} catch (\Throwable) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively remove a directory (best-effort).
|
* Recursively remove a directory (best-effort).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -64,14 +64,19 @@ def make_session(tmpdir: str, auth_key: bytes, dc_id: int) -> str:
|
|||||||
return path + ".session"
|
return path + ".session"
|
||||||
|
|
||||||
|
|
||||||
def convert_to_tdata(session_file: str, out_dir: str):
|
def convert_to_tdata(session_file: str, out_dir: str, user_id: int):
|
||||||
"""Use opentele-ng to convert Telethon session → tdata folder (offline)."""
|
"""Use opentele-ng to convert Telethon session → tdata folder (offline)."""
|
||||||
from opentele.td import TDesktop
|
from opentele.td import TDesktop
|
||||||
from opentele.tl import TelegramClient
|
from opentele.tl import TelegramClient
|
||||||
from opentele.api import UseCurrentSession
|
from opentele.api import UseCurrentSession
|
||||||
|
|
||||||
|
if not user_id:
|
||||||
|
raise ValueError("missing user_id (peerId); cannot convert offline")
|
||||||
|
|
||||||
async def _run():
|
async def _run():
|
||||||
client = TelegramClient(session_file)
|
client = TelegramClient(session_file)
|
||||||
|
# Seed UserId so opentele UseCurrentSession skips get_me() / network.
|
||||||
|
client.UserId = int(user_id)
|
||||||
try:
|
try:
|
||||||
tdesk = await client.ToTDesktop(flag=UseCurrentSession)
|
tdesk = await client.ToTDesktop(flag=UseCurrentSession)
|
||||||
if not tdesk.isLoaded():
|
if not tdesk.isLoaded():
|
||||||
@@ -80,7 +85,10 @@ def convert_to_tdata(session_file: str, out_dir: str):
|
|||||||
shutil.rmtree(out_dir)
|
shutil.rmtree(out_dir)
|
||||||
tdesk.SaveTData(out_dir)
|
tdesk.SaveTData(out_dir)
|
||||||
finally:
|
finally:
|
||||||
|
try:
|
||||||
await client.disconnect()
|
await client.disconnect()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
asyncio.run(_run())
|
asyncio.run(_run())
|
||||||
|
|
||||||
@@ -108,7 +116,7 @@ def main():
|
|||||||
try:
|
try:
|
||||||
session_file = make_session(tmpdir, auth_key, dc_id)
|
session_file = make_session(tmpdir, auth_key, dc_id)
|
||||||
tdata_dir = os.path.join(tmpdir, "tdata")
|
tdata_dir = os.path.join(tmpdir, "tdata")
|
||||||
convert_to_tdata(session_file, tdata_dir)
|
convert_to_tdata(session_file, tdata_dir, user_id)
|
||||||
zip_tdata(tdata_dir, output_zip)
|
zip_tdata(tdata_dir, output_zip)
|
||||||
print(f"wrote {output_zip} ({os.path.getsize(output_zip)} bytes)", file=sys.stderr)
|
print(f"wrote {output_zip} ({os.path.getsize(output_zip)} bytes)", file=sys.stderr)
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
Reference in New Issue
Block a user