p
File size: 3,665 Bytes
1b420ad
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
020cf0e
1b420ad
d9cc270
 
 
 
1b420ad
 
 
 
 
d9cc270
52fadc8
1b420ad
 
 
020cf0e
1b420ad
52fadc8
 
 
1b420ad
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import os
import runpy
import sys
from typing import Dict, Sequence, Tuple

ROOT_DIR = os.path.abspath(os.path.dirname(__file__))
SCRIPTS_DIR = os.path.join(ROOT_DIR, "Scripts")
EXTRACT_DIR = os.path.join(SCRIPTS_DIR, "Extract Pixiv")

RESET = "\x1b[0m"
BOLD = "\x1b[1m"
FG_PRIMARY = "\x1b[38;5;81m"
FG_ACCENT = "\x1b[38;5;214m"
FG_MUTED = "\x1b[38;5;245m"
FG_OK = "\x1b[38;5;120m"
FG_ERROR = "\x1b[38;5;203m"

RULE = "-" * 56
EXIT_KEYS = {"q", "quit", "exit"}

MENU_SECTIONS: Sequence[Tuple[str, Sequence[Tuple[str, str, str]]]] = (
    (
        "Extract Pixiv",
        (
            ("1", "Search (all tags)", os.path.join(EXTRACT_DIR, "search.py")),
            ("2", "Search (AI only)", os.path.join(EXTRACT_DIR, "ai_search.py")),
            ("3", "Search (real only)", os.path.join(EXTRACT_DIR, "real_search.py")),
            ("4", "Users", os.path.join(EXTRACT_DIR, "user.py")),
        ),
    ),
    (
        "Hunt",
        (
            ("5", "Hunt", os.path.join(SCRIPTS_DIR, "hunt.py")),
            ("6", "Scan existing exif", os.path.join(SCRIPTS_DIR, "scan_existing_exif.py")),
        ),
    ),
    (
        "Maintenance",
        (
            ("7", "Clear text logs", os.path.join(SCRIPTS_DIR, "clear_texts.py")),
            ("8", "Clear DB empty rows", os.path.join(SCRIPTS_DIR, "clear_db.py")),
            ("9", "Clear images (except Stash)", os.path.join(SCRIPTS_DIR, "clear_images.py")),
        ),
    ),
)

ACTION_MAP: Dict[str, Tuple[str, str]] = {
    key: (label, path)
    for _, items in MENU_SECTIONS
    for key, label, path in items
}

def style(text: str, *codes: str) -> str:
    if not codes:
        return text
    return "".join(codes) + text + RESET

def print_menu() -> None:
    print(style("Pixif", FG_PRIMARY, BOLD))
    print(style(RULE, FG_MUTED))
    for section, items in MENU_SECTIONS:
        print(style(section, FG_ACCENT, BOLD))
        for key, label, _ in items:
            print(f" {style(key, FG_PRIMARY, BOLD)} {label}")
        print(style(RULE, FG_MUTED))
    print(f" {style('q', FG_MUTED)} Quit")

def run_script(path: str) -> int:
    if not os.path.isfile(path):
        print(style(f"Missing: {path}", FG_ERROR))
        return 1
    original_cwd = os.getcwd()
    original_sys_path = list(sys.path)
    script_dir = os.path.dirname(path)
    sys.path.insert(0, script_dir)
    if ROOT_DIR not in sys.path:
        sys.path.insert(0, ROOT_DIR)
    try:
        os.chdir(ROOT_DIR)
        try:
            runpy.run_path(path, run_name="__main__")
        except SystemExit as exc:
            if isinstance(exc.code, int):
                return exc.code
            return 0
        return 0
    except KeyboardInterrupt:
        print(style("Cancelled.", FG_ERROR))
        return 130
    except Exception as exc:
        print(style(f"Error: {exc}", FG_ERROR))
        return 1
    finally:
        os.chdir(original_cwd)
        sys.path[:] = original_sys_path

def main() -> int:
    os.chdir(ROOT_DIR)
    while True:
        print_menu()
        choice = input(style("Select an option: ", FG_MUTED)).strip().lower()
        if choice in EXIT_KEYS:
            return 0
        action = ACTION_MAP.get(choice)
        if not action:
            print(style("Unknown option.", FG_ERROR))
            continue
        label, path = action
        print(style(f"Running {label}...", FG_PRIMARY, BOLD))
        code = run_script(path)
        if code == 0:
            print(style("Done.", FG_OK))
        else:
            print(style(f"Exit code: {code}", FG_ERROR))
        input(style("Press Enter to return to menu.", FG_MUTED))

if __name__ == "__main__":
    raise SystemExit(main())