Spaces:
Paused
Paused
| 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() |