jettask 0.2.8__py3-none-any.whl → 0.2.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jettask/core/cli.py +126 -36
- {jettask-0.2.8.dist-info → jettask-0.2.9.dist-info}/METADATA +1 -1
- {jettask-0.2.8.dist-info → jettask-0.2.9.dist-info}/RECORD +7 -7
- {jettask-0.2.8.dist-info → jettask-0.2.9.dist-info}/WHEEL +0 -0
- {jettask-0.2.8.dist-info → jettask-0.2.9.dist-info}/entry_points.txt +0 -0
- {jettask-0.2.8.dist-info → jettask-0.2.9.dist-info}/licenses/LICENSE +0 -0
- {jettask-0.2.8.dist-info → jettask-0.2.9.dist-info}/top_level.txt +0 -0
jettask/core/cli.py
CHANGED
@@ -475,28 +475,28 @@ def scheduler(task_center, interval, batch_size, check_interval, debug):
|
|
475
475
|
click.echo("\nShutdown complete")
|
476
476
|
|
477
477
|
@cli.command()
|
478
|
-
@click.option('--port', default=
|
479
|
-
@click.option('--host', default='0.0.0.0', help='
|
478
|
+
@click.option('--port', default=8080, help='前端服务器端口')
|
479
|
+
@click.option('--host', default='0.0.0.0', help='前端服务器监听地址')
|
480
480
|
@click.option('--auto-install', is_flag=True, default=True, help='自动安装缺失的依赖')
|
481
481
|
@click.option('--force-install', is_flag=True, help='强制重新安装依赖')
|
482
|
-
@click.option('--build', is_flag=True, help='
|
483
|
-
def frontend(port, host, auto_install, force_install,
|
482
|
+
@click.option('--build-only', is_flag=True, help='仅构建生产版本,不启动服务器')
|
483
|
+
def frontend(port, host, auto_install, force_install, build_only):
|
484
484
|
"""启动 WebUI 前端界面
|
485
485
|
|
486
|
-
|
486
|
+
启动生产版本服务器:
|
487
487
|
1. 检查 Node.js 和 npm 是否安装
|
488
|
-
2.
|
489
|
-
3.
|
488
|
+
2. 复制前端代码到用户目录并安装依赖
|
489
|
+
3. 构建并启动生产版本服务器
|
490
490
|
|
491
491
|
示例:
|
492
|
-
#
|
492
|
+
# 启动生产版本服务器(默认)
|
493
493
|
jettask frontend
|
494
494
|
|
495
495
|
# 指定端口
|
496
496
|
jettask frontend --port 3000
|
497
497
|
|
498
|
-
#
|
499
|
-
jettask frontend --build
|
498
|
+
# 仅构建生产版本
|
499
|
+
jettask frontend --build-only
|
500
500
|
|
501
501
|
# 强制重新安装依赖
|
502
502
|
jettask frontend --force-install
|
@@ -505,12 +505,79 @@ def frontend(port, host, auto_install, force_install, build):
|
|
505
505
|
import shutil
|
506
506
|
from pathlib import Path
|
507
507
|
|
508
|
-
#
|
509
|
-
|
510
|
-
if not
|
511
|
-
click.echo(f"
|
508
|
+
# 获取源前端目录路径(包中的)
|
509
|
+
source_frontend_dir = Path(__file__).parent.parent / "webui" / "frontend"
|
510
|
+
if not source_frontend_dir.exists():
|
511
|
+
click.echo(f"错误:前端源目录不存在: {source_frontend_dir}", err=True)
|
512
512
|
sys.exit(1)
|
513
513
|
|
514
|
+
# 获取用户工作目录(在用户主目录下)
|
515
|
+
user_home = Path.home()
|
516
|
+
user_jettask_dir = user_home / ".jettask"
|
517
|
+
user_frontend_dir = user_jettask_dir / "frontend"
|
518
|
+
|
519
|
+
# 确保用户目录存在
|
520
|
+
user_jettask_dir.mkdir(parents=True, exist_ok=True)
|
521
|
+
|
522
|
+
# 检查是否需要复制/更新前端代码
|
523
|
+
should_copy = False
|
524
|
+
if not user_frontend_dir.exists():
|
525
|
+
should_copy = True
|
526
|
+
click.echo(f"首次使用,正在初始化前端环境...")
|
527
|
+
else:
|
528
|
+
# 检查版本或时间戳来决定是否需要更新
|
529
|
+
source_package_json = source_frontend_dir / "package.json"
|
530
|
+
user_package_json = user_frontend_dir / "package.json"
|
531
|
+
if not user_package_json.exists():
|
532
|
+
should_copy = True
|
533
|
+
else:
|
534
|
+
# 比较修改时间
|
535
|
+
if source_package_json.stat().st_mtime > user_package_json.stat().st_mtime:
|
536
|
+
should_copy = True
|
537
|
+
click.echo("检测到前端代码更新,正在同步...")
|
538
|
+
|
539
|
+
if should_copy:
|
540
|
+
# 复制前端代码到用户目录
|
541
|
+
if user_frontend_dir.exists():
|
542
|
+
# 保留 node_modules 和 dist 目录
|
543
|
+
node_modules_backup = None
|
544
|
+
dist_backup = None
|
545
|
+
|
546
|
+
node_modules_dir = user_frontend_dir / "node_modules"
|
547
|
+
dist_dir = user_frontend_dir / "dist"
|
548
|
+
|
549
|
+
if node_modules_dir.exists() and not force_install:
|
550
|
+
# 备份 node_modules
|
551
|
+
node_modules_backup = user_jettask_dir / "node_modules_backup"
|
552
|
+
if node_modules_backup.exists():
|
553
|
+
shutil.rmtree(node_modules_backup)
|
554
|
+
shutil.move(str(node_modules_dir), str(node_modules_backup))
|
555
|
+
|
556
|
+
if dist_dir.exists():
|
557
|
+
# 备份 dist
|
558
|
+
dist_backup = user_jettask_dir / "dist_backup"
|
559
|
+
if dist_backup.exists():
|
560
|
+
shutil.rmtree(dist_backup)
|
561
|
+
shutil.move(str(dist_dir), str(dist_backup))
|
562
|
+
|
563
|
+
# 删除旧的前端目录
|
564
|
+
shutil.rmtree(user_frontend_dir)
|
565
|
+
|
566
|
+
# 复制新的前端代码
|
567
|
+
shutil.copytree(source_frontend_dir, user_frontend_dir, ignore=shutil.ignore_patterns('node_modules', 'dist', '.git'))
|
568
|
+
|
569
|
+
# 恢复备份
|
570
|
+
if 'node_modules_backup' in locals() and node_modules_backup and node_modules_backup.exists():
|
571
|
+
shutil.move(str(node_modules_backup), str(user_frontend_dir / "node_modules"))
|
572
|
+
|
573
|
+
if 'dist_backup' in locals() and dist_backup and dist_backup.exists():
|
574
|
+
shutil.move(str(dist_backup), str(user_frontend_dir / "dist"))
|
575
|
+
|
576
|
+
click.echo(f"✓ 前端代码已同步到: {user_frontend_dir}")
|
577
|
+
|
578
|
+
# 工作目录切换到用户前端目录
|
579
|
+
frontend_dir = user_frontend_dir
|
580
|
+
|
514
581
|
# 检查 Node.js 是否安装
|
515
582
|
node_cmd = shutil.which('node')
|
516
583
|
if not node_cmd:
|
@@ -541,7 +608,7 @@ def frontend(port, host, auto_install, force_install, build):
|
|
541
608
|
|
542
609
|
# 切换到前端目录
|
543
610
|
os.chdir(frontend_dir)
|
544
|
-
click.echo(f"
|
611
|
+
click.echo(f"工作目录: {frontend_dir}")
|
545
612
|
|
546
613
|
# 检查 package.json 是否存在
|
547
614
|
package_json = frontend_dir / "package.json"
|
@@ -583,48 +650,71 @@ def frontend(port, host, auto_install, force_install, build):
|
|
583
650
|
|
584
651
|
# 构建或启动
|
585
652
|
try:
|
586
|
-
|
587
|
-
|
653
|
+
# 构建生产版本
|
654
|
+
dist_dir = frontend_dir / "dist"
|
655
|
+
|
656
|
+
# 检查是否需要构建
|
657
|
+
need_build = not dist_dir.exists() or build_only
|
658
|
+
|
659
|
+
# 如果 dist 不存在或明确要求构建,则进行构建
|
660
|
+
if need_build:
|
588
661
|
click.echo("\n正在构建生产版本...")
|
589
662
|
subprocess.run([npm_cmd, 'run', 'build'], check=True)
|
590
663
|
|
591
|
-
# 显示构建结果
|
592
|
-
dist_dir = frontend_dir.parent / "static" / "dist"
|
593
664
|
if dist_dir.exists():
|
594
|
-
click.echo(f"\n✓ 构建完成!输出目录: {dist_dir}")
|
595
665
|
# 统计文件
|
596
666
|
files = list(dist_dir.rglob('*'))
|
597
667
|
file_count = len([f for f in files if f.is_file()])
|
598
668
|
total_size = sum(f.stat().st_size for f in files if f.is_file())
|
669
|
+
click.echo(f"\n✓ 构建完成!")
|
670
|
+
click.echo(f" - 输出目录: {dist_dir}")
|
599
671
|
click.echo(f" - 文件数量: {file_count}")
|
600
672
|
click.echo(f" - 总大小: {total_size / 1024 / 1024:.2f} MB")
|
601
673
|
else:
|
602
|
-
click.echo("
|
603
|
-
|
604
|
-
|
605
|
-
|
674
|
+
click.echo("错误:构建失败,未生成输出目录", err=True)
|
675
|
+
sys.exit(1)
|
676
|
+
|
677
|
+
# 如果不是仅构建模式,启动生产服务器
|
678
|
+
if not build_only:
|
679
|
+
if not dist_dir.exists():
|
680
|
+
click.echo("错误:未找到构建输出,请先运行构建", err=True)
|
681
|
+
sys.exit(1)
|
682
|
+
|
683
|
+
click.echo(f"\n正在启动生产版本服务器...")
|
606
684
|
click.echo(f" - 地址: http://{host}:{port}")
|
607
685
|
click.echo(f" - 本地访问: http://localhost:{port}")
|
686
|
+
click.echo(f" - 静态文件目录: {dist_dir}")
|
608
687
|
click.echo("\n按 Ctrl+C 停止服务器\n")
|
609
688
|
|
610
|
-
#
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
689
|
+
# 使用 Python 内置的 HTTP 服务器提供静态文件
|
690
|
+
import http.server
|
691
|
+
import socketserver
|
692
|
+
|
693
|
+
class Handler(http.server.SimpleHTTPRequestHandler):
|
694
|
+
def __init__(self, *args, **kwargs):
|
695
|
+
super().__init__(*args, directory=str(dist_dir), **kwargs)
|
696
|
+
|
697
|
+
def do_GET(self):
|
698
|
+
# 对于 SPA 应用,所有路由都返回 index.html
|
699
|
+
if self.path != '/' and not Path(dist_dir / self.path[1:]).exists():
|
700
|
+
self.path = '/index.html'
|
701
|
+
return super().do_GET()
|
702
|
+
|
703
|
+
def log_message(self, format, *args):
|
704
|
+
# 自定义日志格式
|
705
|
+
click.echo(f"[{self.log_date_time_string()}] {format % args}")
|
616
706
|
|
617
|
-
#
|
618
|
-
|
619
|
-
|
707
|
+
# 创建服务器
|
708
|
+
with socketserver.TCPServer((host, port), Handler) as httpd:
|
709
|
+
try:
|
710
|
+
httpd.serve_forever()
|
711
|
+
except KeyboardInterrupt:
|
712
|
+
pass
|
620
713
|
except subprocess.CalledProcessError as e:
|
621
714
|
click.echo(f"错误:命令执行失败 - {e}", err=True)
|
622
715
|
sys.exit(1)
|
623
716
|
except KeyboardInterrupt:
|
624
717
|
click.echo("\n停止前端服务器")
|
625
|
-
if 'process' in locals():
|
626
|
-
process.terminate()
|
627
|
-
process.wait()
|
628
718
|
|
629
719
|
def main():
|
630
720
|
"""主入口函数"""
|
@@ -7,7 +7,7 @@ jettask/config/performance.py,sha256=bOdLEskfB_6cRfS10IRgmtKEsJw_CaIZsPHbXxaHwbU
|
|
7
7
|
jettask/core/__init__.py,sha256=CvBoBCERXCo-jgnkPqAuIgT4uC7oQMnSi7okRxMi6Vc,181
|
8
8
|
jettask/core/app.py,sha256=D6wqdGIVR8E1a7RNevNDaICfKGDsea4RqS9aRlMU810,74906
|
9
9
|
jettask/core/app_importer.py,sha256=B8WiSUz5_O5jlFIBr1CxI_F2gqFYK6ItpONiY_4AiXI,10266
|
10
|
-
jettask/core/cli.py,sha256=
|
10
|
+
jettask/core/cli.py,sha256=yXbIh8e6U2VnBq6t_vB0zbhGTfMjKW2qnWkR8E-Ehn4,28477
|
11
11
|
jettask/core/consumer_manager.py,sha256=7z3IBvH85YD61ZkVNfOVsuP5NaAwV2Ki8aVz9TCplAM,79870
|
12
12
|
jettask/core/context.py,sha256=XI4Q1s75NIWImcrHIkCLgGo_kpuJIk8MlBoNIJuEfF0,993
|
13
13
|
jettask/core/delay_scanner.py,sha256=rwbIA7SFyOxAV14FW7NB40_djFrrqJJpNkpOri7XcZI,8394
|
@@ -164,9 +164,9 @@ jettask/webui/models/__init__.py,sha256=5cv0oZksj1B3_rzCqsPmF3Gn9NRZLwzMnaJ8bOKG
|
|
164
164
|
jettask/webui/models/namespace.py,sha256=jDj-hZF_-wXzrWAWVDyZVU0JUWDax9apb4Gyykwg-rE,2006
|
165
165
|
jettask/webui/sql/batch_upsert_functions.sql,sha256=5eWOhOD8gWHhtcop_BrCpZTxPFeyBHtt_leNQZO89Cs,6615
|
166
166
|
jettask/webui/sql/init_database.sql,sha256=CSjhBZldtfV0SGBLTFf576ALaRfCFe3wywpezzkX1TQ,22369
|
167
|
-
jettask-0.2.
|
168
|
-
jettask-0.2.
|
169
|
-
jettask-0.2.
|
170
|
-
jettask-0.2.
|
171
|
-
jettask-0.2.
|
172
|
-
jettask-0.2.
|
167
|
+
jettask-0.2.9.dist-info/licenses/LICENSE,sha256=sKR8OPWvnqxzcHAmnaVSANpRpeM0Z52PNLCB0ZlFN6c,1062
|
168
|
+
jettask-0.2.9.dist-info/METADATA,sha256=o1iIWSh4caLbG86b_qodkYtVdBoDUldjUZKnrGGlcNI,2955
|
169
|
+
jettask-0.2.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
170
|
+
jettask-0.2.9.dist-info/entry_points.txt,sha256=VC3byRkkSfRHu_QzczGtpGjcFERkJUlCrD__TFLVqxI,153
|
171
|
+
jettask-0.2.9.dist-info/top_level.txt,sha256=uymyRUF87-OsSurk5NhpeTW0jy3Wltnn91Zoa6jmAaw,8
|
172
|
+
jettask-0.2.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|