File size: 7,537 Bytes
2f1852d
18b8d68
b566b4a
adb8fb7
 
3d55d43
2c8d979
adb8fb7
2f1852d
b566b4a
126d4d0
b401ca4
b566b4a
2f1852d
 
 
3d55d43
126d4d0
 
 
2df215d
15f27f7
 
 
0f85143
126d4d0
2f1852d
f68c84d
 
 
126d4d0
f68c84d
126d4d0
 
 
 
 
 
 
f68c84d
126d4d0
 
 
 
 
f68c84d
126d4d0
 
 
 
 
f68c84d
 
47aedf2
126d4d0
2f1852d
126d4d0
 
3af8464
126d4d0
b566b4a
126d4d0
 
 
 
 
b566b4a
3d55d43
b401ca4
126d4d0
b401ca4
 
 
 
b566b4a
3d55d43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b566b4a
3d55d43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c38e967
47aedf2
2f1852d
f68c84d
b401ca4
93f9458
126d4d0
3d55d43
 
 
 
 
b401ca4
3d55d43
 
2df215d
 
 
9e57a76
c38e967
 
3d55d43
c38e967
 
 
3af8464
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
import os
import json
import re
import requests
import gradio as gr
from huggingface_hub import HfApi, hf_hub_download

# 環境変数から取得
HF_TOKEN = os.environ.get("HF_TOKEN", None)
MODEL_REPO = os.environ.get("MODEL_REPO", None)
LORA_REPO = os.environ.get("LORA_REPO", None)
EMBE_REPO = os.environ.get("EMBE_REPO", None)  # embedding用リポジトリ
CIVITAI_TOKEN = os.environ.get("CIVITAI_TOKEN", None)  # Civitai用トークン

api = HfApi()

def download_and_upload(model_id, repo_type):
    print(f"モデルID: {model_id}, リポジトリタイプ: {repo_type}")
    if not model_id or not repo_type:
        return "モデルIDまたはタイプが未指定です。"

    headers = {}
    if CIVITAI_TOKEN:
        headers["Authorization"] = f"Bearer {CIVITAI_TOKEN}"

    # モデル情報の取得
    try:
        response = requests.get(f"https://civitai.com/api/v1/models/{model_id}", headers=headers)
        response.raise_for_status()
        model_data = response.json()
        print("モデル情報を取得しました。")
    except Exception as e:
        print(f"モデル情報の取得に失敗しました: {e}")
        return f"モデル情報の取得に失敗しました: {e}"

    # 最新のモデルバージョンを取得
    model_versions = model_data.get("modelVersions", [])
    if not model_versions:
        return "モデルバージョンが見つかりませんでした。"

    latest_version = model_versions[0]  # 最新バージョンを取得
    trigger_words = latest_version.get("trainedWords", [])
    files = latest_version.get("files", [])
    if not files:
        return "モデルファイルが見つかりませんでした。"

    download_url = files[0].get("downloadUrl")
    if not download_url:
        return "ダウンロードURLが見つかりませんでした。"

    # ファイルのダウンロード
    try:
        response = requests.get(download_url, headers=headers)
        response.raise_for_status()
        print("ファイルをダウンロードしました。")
    except Exception as e:
        print(f"ファイルのダウンロードに失敗しました: {e}")
        return f"ファイルのダウンロードに失敗しました: {e}"

    # ファイル名の設定
    filename = files[0].get("name", "downloaded_file.bin")

    with open(filename, "wb") as f:
        f.write(response.content)
    print(f"ファイルを保存しました: {filename}")

    if repo_type == "model":
        target_repo = MODEL_REPO
    elif repo_type == "lora":
        target_repo = LORA_REPO
    elif repo_type == "embedding":
        target_repo = EMBE_REPO
    else:
        return "不正なリポジトリタイプです。"

    if not target_repo:
        return f"{repo_type}用リポジトリが環境変数で設定されていません。"

    # リポジトリ内のファイル一覧を取得
    try:
        repo_files = api.list_repo_files(repo_id=target_repo, repo_type="dataset", token=HF_TOKEN)
        print(f"リポジトリ内のファイル一覧を取得しました。")
    except Exception as e:
        print(f"リポジトリ内のファイル一覧の取得に失敗しました: {e}")
        return f"リポジトリ内のファイル一覧の取得に失敗しました: {e}"

    # メタデータファイル名
    metadata_filename = "metadata.json"

    # リポジトリからメタデータファイルをダウンロード
    try:
        metadata_file = hf_hub_download(
            repo_id=target_repo,
            filename=metadata_filename,
            repo_type="dataset",
            token=HF_TOKEN,
            force_download=True
        )
        with open(metadata_file, 'r', encoding='utf-8') as f:
            metadata = json.load(f)
        print("既存のメタデータを読み込みました。")
    except Exception as e:
        # メタデータファイルが存在しない場合は新規作成
        metadata = []
        print("メタデータファイルが存在しないため、新規作成します。")

    # メタデータを更新(存在しないファイルを削除)
    updated_metadata = []
    for entry in metadata:
        if entry['filename'] in repo_files:
            updated_metadata.append(entry)
        else:
            print(f"存在しないファイルのメタデータを削除: {entry['filename']}")

    # ファイル名の重複チェック
    existing_filenames = [e['filename'] for e in updated_metadata]
    if filename in existing_filenames:
        print(f"ファイル名が既に存在します。ファイル名: {filename}")
        return f"ファイル名 '{filename}' は既にリポジトリに存在します。"

    # 新しい通し番号の設定
    sequence_numbers = [e['sequence_number'] for e in updated_metadata]
    if sequence_numbers:
        new_sequence_number = max(sequence_numbers) + 1
    else:
        new_sequence_number = 1

    # 新しいエントリを追加
    new_entry = {
        "sequence_number": new_sequence_number,
        "filename": filename,
        "trigger_words": trigger_words
    }
    updated_metadata.append(new_entry)
    print(f"新しいメタデータを追加しました: {new_entry}")

    # メタデータをファイルに保存
    with open(metadata_filename, 'w', encoding='utf-8') as f:
        json.dump(updated_metadata, f, ensure_ascii=False, indent=4)
    print(f"メタデータファイルを更新しました。ファイル名: {metadata_filename}")

    # ファイルのアップロード
    try:
        # 元のファイルをアップロード
        api.upload_file(
            path_or_fileobj=filename,
            path_in_repo=filename,
            repo_id=target_repo,
            token=HF_TOKEN,
            repo_type="dataset",
            commit_message=f"Add {filename} from model ID {model_id}"
        )

        # 更新したメタデータファイルをアップロード
        api.upload_file(
            path_or_fileobj=metadata_filename,
            path_in_repo=metadata_filename,
            repo_id=target_repo,
            token=HF_TOKEN,
            repo_type="dataset",
            commit_message="Update metadata"
        )
        print(f"ファイルとメタデータをアップロードしました。")
        return f"ファイル '{filename}' とメタデータを '{target_repo}' にアップロードしました。"
    except Exception as e:
        print(f"アップロード中にエラーが発生しました: {e}")
        return f"アップロード中にエラーが発生しました: {e}"

# Gradio UI構築
with gr.Blocks() as demo:
    gr.Markdown("## CivitaiモデルIDからファイルダウンロード&アップロードツール")
    gr.Markdown("CivitaiのモデルIDを指定して、'model'、'lora'、または'embedding'リポジトリへアップロードします。")

    # ダウンロード&アップロード機能
    model_id_input = gr.Textbox(
        label="CivitaiモデルID",
        placeholder="例: 1102"
    )
    repo_choice = gr.Radio(
        choices=["model", "lora", "embedding"],  # "embedding" を追加
        label="アップロード先タイプの選択",
        value="model"
    )
    run_button = gr.Button("実行")
    output = gr.Textbox(label="結果メッセージ", interactive=False)

    run_button.click(
        download_and_upload,
        inputs=[model_id_input, repo_choice],
        outputs=output
    )

demo.launch()