File size: 3,049 Bytes
5edd1d1
 
 
 
 
01b7406
66cc8a2
5edd1d1
9d3c5b6
5edd1d1
 
 
91ca39f
9d3c5b6
01b7406
 
 
9d3c5b6
2a132c9
ddba765
bdc9828
 
 
9d3c5b6
 
ddba765
9d3c5b6
 
bdc9828
9d3c5b6
bdc9828
9d3c5b6
 
bdc9828
66cc8a2
01b7406
bdc9828
b4b8616
66cc8a2
9d3c5b6
b4b8616
5edd1d1
9d3c5b6
5edd1d1
 
9d3c5b6
 
 
 
 
 
 
 
bdc9828
9d3c5b6
bdc9828
 
 
 
 
2a132c9
bdc9828
9d3c5b6
01b7406
5edd1d1
 
9d3c5b6
 
ddba765
5edd1d1
bdc9828
5edd1d1
91ca39f
 
 
 
 
 
9d3c5b6
 
03c7cd2
5edd1d1
91ca39f
 
 
 
 
 
b3ca796
bdc9828
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
import gradio as gr
import os
import shutil
from huggingface_hub import HfApi, HfFolder, snapshot_download

# ローカル / デプロイ共通の環境トークン(あれば)
ENV_HF_TOKEN = os.getenv("HF_TOKEN")
api = HfApi()

target_space = "s-4-s/pre-s4s-editor"
local_dir = "./space_copy"

def run_clone(source_space: str, profile: gr.OAuthProfile | None, oauth_token: gr.OAuthToken | None):
    """
    注意: Gradio は profile と oauth_token を自動注入します。
    - profile が None => 未ログイン
    - oauth_token が None でも、ENV_HF_TOKEN があればそれを使う(ローカルデバッグ用)
    """
    logs = ""

    def log(msg: str):
        nonlocal logs
        logs += msg + "\n"
        yield logs

    try:
        hf_token = oauth_token.token if oauth_token is not None else ENV_HF_TOKEN

        if profile is None:
            yield from log("❌ 未ログインです。先にログインしてください。")
            return
        if getattr(profile, "username", None) != "soiz1":
            yield from log(f"❌ アクセス拒否: {getattr(profile, 'username', '不明')}")
            return
        if hf_token is None:
            yield from log("❌ 実行に必要な Hugging Face トークンが見つかりません。")
            return

        HfFolder.save_token(hf_token)
        yield from log("=== Hugging Face Space クローン開始 ===")

        if os.path.exists(local_dir):
            yield from log(f"既存の '{local_dir}' を削除します...")
            shutil.rmtree(local_dir)

        yield from log(f"'{source_space}' をローカルにダウンロード中...")
        snapshot_download(
            repo_id=source_space,
            repo_type="space",
            local_dir=local_dir,
            token=hf_token
        )
        yield from log(f"'{source_space}' を '{local_dir}' にダウンロードしました。")

        yield from log(f"'{target_space}' へアップロード中...")
        api.upload_folder(
            folder_path=local_dir,
            repo_id=target_space,
            repo_type="space",
            token=hf_token,
            commit_message="自動クローン"
        )
        yield from log(f"'{source_space}' の内容を '{target_space}' にアップロードしました。")
        yield from log("=== 処理完了 ===")

    except Exception as e:
        yield from log(f"エラー発生: {e}")


with gr.Blocks() as demo:
    gr.Markdown("## 🚀 Hugging Face Space 自動クローンツール")

    source_space_input = gr.Textbox(
        label="ソース Space",
        value="soiz1/soiz1-s4s-editor",
        lines=1,
    )

    gr.LoginButton()
    run_button = gr.Button("クローン & アップロード開始", interactive=True)
    log_output = gr.Textbox(label="ログ出力", lines=20, interactive=False)

    # source_space_input も inputs に渡す
    run_button.click(
        fn=run_clone,
        inputs=[source_space_input],
        outputs=log_output,
    )

demo.launch()