John6666 commited on
Commit
08cbaa7
1 Parent(s): 8c84074

Upload 3 files

Browse files
Files changed (2) hide show
  1. app.py +17 -10
  2. civitai_to_hf.py +94 -5
app.py CHANGED
@@ -3,6 +3,7 @@ from civitai_to_hf import search_civitai, download_civitai, select_civitai_item,
3
 
4
  css = """
5
  .title { font-size: 3em; align-items: center; text-align: center; }
 
6
  .block.result { margin: 1em 0; padding: 1em; box-shadow: 0 0 3px 3px #664422, 0 0 3px 2px #664422 inset; border-radius: 6px; background: #665544; }
7
  """
8
 
@@ -21,28 +22,34 @@ with gr.Blocks(theme="NoCrypt/miku@>=1.2.2", fill_width=True, css=css, delete_ca
21
  search_civitai_tag = gr.Textbox(label="Tag", lines=1)
22
  search_civitai_submit = gr.Button("Search on Civitai")
23
  with gr.Row():
24
- search_civitai_json = gr.JSON(value={}, visible=False)
25
  search_civitai_desc = gr.Markdown(value="", visible=False)
 
26
  search_civitai_result = gr.Dropdown(label="Search Results", choices=[("", "")], value="", allow_custom_value=True, visible=False, multiselect=True)
27
  search_civitai_add = gr.Button("Add to download URLs")
28
- dl_url = gr.Textbox(label="Download URL(s)", placeholder="https://civitai.com/api/download/models/28907\n...", value="", lines=2, max_lines=255)
29
- civitai_key = gr.Textbox(label="Your Civitai Key", value="", max_lines=1)
30
- with gr.Row():
31
- hf_token = gr.Textbox(label="Your HF write token", placeholder="hf_...", value="", max_lines=1)
32
- gr.Markdown("Your token is available at [hf.co/settings/tokens](https://huggingface.co/settings/tokens).")
 
 
 
 
 
 
33
  with gr.Row():
34
- newrepo_id = gr.Textbox(label="Upload repo ID", placeholder="yourid/yourrepo", value="", max_lines=1)
35
  newrepo_type = gr.Radio(label="Upload repo type", choices=["model", "dataset"], value="model")
36
  is_private = gr.Checkbox(label="Create private repo", value=True)
 
 
37
  uploaded_urls = gr.CheckboxGroup(visible=False, choices=[], value=None) # hidden
38
- run_button = gr.Button(value="Download and Upload")
39
  urls_md = gr.Markdown("<br><br>", elem_classes="result")
40
  gr.DuplicateButton(value="Duplicate Space")
41
 
42
  gr.on(
43
  triggers=[run_button.click],
44
  fn=download_civitai,
45
- inputs=[dl_url, civitai_key, hf_token, uploaded_urls, newrepo_id, newrepo_type, is_private],
46
  outputs=[uploaded_urls, urls_md],
47
  )
48
  gr.on(
@@ -53,7 +60,7 @@ with gr.Blocks(theme="NoCrypt/miku@>=1.2.2", fill_width=True, css=css, delete_ca
53
  queue=True,
54
  show_api=False,
55
  )
56
- search_civitai_result.change(select_civitai_item, [search_civitai_result], [search_civitai_desc], queue=False, show_api=False)
57
  search_civitai_add.click(add_civitai_item, [search_civitai_result, dl_url], [dl_url], queue=False, show_api=False)
58
 
59
  demo.queue()
 
3
 
4
  css = """
5
  .title { font-size: 3em; align-items: center; text-align: center; }
6
+ .info { align-items: center; text-align: center; }
7
  .block.result { margin: 1em 0; padding: 1em; box-shadow: 0 0 3px 3px #664422, 0 0 3px 2px #664422 inset; border-radius: 6px; background: #665544; }
8
  """
9
 
 
22
  search_civitai_tag = gr.Textbox(label="Tag", lines=1)
23
  search_civitai_submit = gr.Button("Search on Civitai")
24
  with gr.Row():
 
25
  search_civitai_desc = gr.Markdown(value="", visible=False)
26
+ search_civitai_json = gr.JSON(value={}, visible=False)
27
  search_civitai_result = gr.Dropdown(label="Search Results", choices=[("", "")], value="", allow_custom_value=True, visible=False, multiselect=True)
28
  search_civitai_add = gr.Button("Add to download URLs")
29
+ with gr.Group():
30
+ dl_url = gr.Textbox(label="Download URL(s)", placeholder="https://civitai.com/api/download/models/28907\n...", value="", lines=3, max_lines=255)
31
+ with gr.Column():
32
+ civitai_key = gr.Textbox(label="Your Civitai Key", value="", max_lines=1)
33
+ gr.Markdown("Your Civitai API key is available at [https://civitai.com/user/account](https://civitai.com/user/account).", elem_classes="info")
34
+ with gr.Group():
35
+ with gr.Row():
36
+ with gr.Column():
37
+ hf_token = gr.Textbox(label="Your HF write token", placeholder="hf_...", value="", max_lines=1)
38
+ gr.Markdown("Your token is available at [hf.co/settings/tokens](https://huggingface.co/settings/tokens).", elem_classes="info")
39
+ newrepo_id = gr.Textbox(label="Upload repo ID", placeholder="yourid/yourrepo", value="", max_lines=1)
40
  with gr.Row():
 
41
  newrepo_type = gr.Radio(label="Upload repo type", choices=["model", "dataset"], value="model")
42
  is_private = gr.Checkbox(label="Create private repo", value=True)
43
+ is_info = gr.Checkbox(label="Upload Civitai information files", value=False)
44
+ run_button = gr.Button(value="Download and Upload", variant="primary")
45
  uploaded_urls = gr.CheckboxGroup(visible=False, choices=[], value=None) # hidden
 
46
  urls_md = gr.Markdown("<br><br>", elem_classes="result")
47
  gr.DuplicateButton(value="Duplicate Space")
48
 
49
  gr.on(
50
  triggers=[run_button.click],
51
  fn=download_civitai,
52
+ inputs=[dl_url, civitai_key, hf_token, uploaded_urls, newrepo_id, newrepo_type, is_private, is_info],
53
  outputs=[uploaded_urls, urls_md],
54
  )
55
  gr.on(
 
60
  queue=True,
61
  show_api=False,
62
  )
63
+ search_civitai_result.change(select_civitai_item, [search_civitai_result], [search_civitai_desc, search_civitai_json], queue=False, show_api=False)
64
  search_civitai_add.click(add_civitai_item, [search_civitai_result, dl_url], [dl_url], queue=False, show_api=False)
65
 
66
  demo.queue()
civitai_to_hf.py CHANGED
@@ -8,6 +8,11 @@ from requests.adapters import HTTPAdapter
8
  from urllib3.util import Retry
9
  from utils import get_token, set_token, is_repo_exists, get_user_agent, get_download_file, list_uniq
10
  import re
 
 
 
 
 
11
 
12
 
13
  def parse_urls(s):
@@ -41,18 +46,61 @@ def upload_safetensors_to_repo(filename, repo_id, repo_type, is_private, progres
41
  print(f"Error: Failed to upload to {repo_id}. {e}")
42
  gr.Warning(f"Error: Failed to upload to {repo_id}. {e}")
43
  return None
 
 
44
  return url
45
 
46
 
47
  def download_file(dl_url, civitai_key, progress=gr.Progress(track_tqdm=True)):
48
- download_dir = "."
49
  progress(0, desc=f"Start downloading... {dl_url}")
50
  output_filename = get_download_file(download_dir, dl_url, civitai_key)
51
  return output_filename
52
 
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  def download_civitai(dl_url, civitai_key, hf_token, urls,
55
- newrepo_id, repo_type="model", is_private=True, progress=gr.Progress(track_tqdm=True)):
56
  if hf_token: set_token(hf_token)
57
  else: set_token(os.environ.get("HF_TOKEN")) # default huggingface write token
58
  if not civitai_key: civitai_key = os.environ.get("CIVITAI_API_KEY") # default Civitai API key
@@ -64,8 +112,9 @@ def download_civitai(dl_url, civitai_key, hf_token, urls,
64
  file = download_file(u, civitai_key)
65
  if not Path(file).exists() or not Path(file).is_file(): continue
66
  url = upload_safetensors_to_repo(file, newrepo_id, repo_type, is_private)
67
- if url: urls.append(url)
68
- Path(file).unlink()
 
69
  progress(1, desc="Processing...")
70
  md = f'### Your repo: [{newrepo_id}]({"https://huggingface.co/datasets/" if repo_type == "dataset" else "https://huggingface.co/"}{newrepo_id})\n'
71
  for u in urls:
@@ -143,11 +192,51 @@ def search_civitai(query, types, base_model=[], sort=CIVITAI_SORT[0], period=CIV
143
  gr.update(visible=True), gr.update(visible=True)
144
 
145
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  def select_civitai_item(results: list[str]):
147
  if "http" not in "".join(results): return gr.update(value="None", visible=True)
148
  result = civitai_last_results.get(results[-1], "None")
149
  md = result['md'] if result else ""
150
- return gr.update(value=md, visible=True)
 
 
151
 
152
 
153
  def add_civitai_item(results: list[str], dl_url: str):
 
8
  from urllib3.util import Retry
9
  from utils import get_token, set_token, is_repo_exists, get_user_agent, get_download_file, list_uniq
10
  import re
11
+ from PIL import Image
12
+ import json
13
+
14
+
15
+ TEMP_DIR = "."
16
 
17
 
18
  def parse_urls(s):
 
46
  print(f"Error: Failed to upload to {repo_id}. {e}")
47
  gr.Warning(f"Error: Failed to upload to {repo_id}. {e}")
48
  return None
49
+ finally:
50
+ Path(filename).unlink()
51
  return url
52
 
53
 
54
  def download_file(dl_url, civitai_key, progress=gr.Progress(track_tqdm=True)):
55
+ download_dir = TEMP_DIR
56
  progress(0, desc=f"Start downloading... {dl_url}")
57
  output_filename = get_download_file(download_dir, dl_url, civitai_key)
58
  return output_filename
59
 
60
 
61
+ def save_civitai_info(dl_url, filename, progress=gr.Progress(track_tqdm=True)):
62
+ json_str, html_str, image_path = get_civitai_json(dl_url, True, filename)
63
+ if not json_str: return "", "", ""
64
+ json_path = str(Path(TEMP_DIR, Path(filename).stem + ".json"))
65
+ html_path = str(Path(TEMP_DIR, Path(filename).stem + ".html"))
66
+ try:
67
+ with open(json_path, 'w') as f:
68
+ json.dump(json_str, f, indent=2)
69
+ with open(html_path, mode='w', encoding="utf-8") as f:
70
+ f.write(html_str)
71
+ return json_path, html_path, image_path
72
+ except Exception as e:
73
+ print(f"Error: Failed to save info file {json_path}, {html_path} {e}")
74
+ return "", "", ""
75
+
76
+
77
+ def upload_info_to_repo(dl_url, filename, repo_id, repo_type, is_private, progress=gr.Progress(track_tqdm=True)):
78
+ def upload_file(api, filename, repo_id, repo_type, hf_token):
79
+ if not Path(filename).exists(): return
80
+ api.upload_file(path_or_fileobj=filename, path_in_repo=Path(filename).name, repo_type=repo_type, revision="main", token=hf_token, repo_id=repo_id)
81
+ Path(filename).unlink()
82
+
83
+ hf_token = get_token()
84
+ api = HfApi(token=hf_token)
85
+ try:
86
+ if not is_repo_exists(repo_id, repo_type): api.create_repo(repo_id=repo_id, repo_type=repo_type, token=hf_token, private=is_private)
87
+ progress(0, desc=f"Downloading info... {filename}")
88
+ json_path, html_path, image_path = save_civitai_info(dl_url, filename)
89
+ progress(0, desc=f"Start uploading info... {filename} to {repo_id}")
90
+ if not json_path: return
91
+ else: upload_file(api, json_path, repo_id, repo_type, hf_token)
92
+ if html_path: upload_file(api, html_path, repo_id, repo_type, hf_token)
93
+ if image_path: upload_file(api, image_path, repo_id, repo_type, hf_token)
94
+ progress(1, desc="Info uploaded.")
95
+ return
96
+ except Exception as e:
97
+ print(f"Error: Failed to upload info to {repo_id}. {e}")
98
+ gr.Warning(f"Error: Failed to upload info to {repo_id}. {e}")
99
+ return
100
+
101
+
102
  def download_civitai(dl_url, civitai_key, hf_token, urls,
103
+ newrepo_id, repo_type="model", is_private=True, is_info=False, progress=gr.Progress(track_tqdm=True)):
104
  if hf_token: set_token(hf_token)
105
  else: set_token(os.environ.get("HF_TOKEN")) # default huggingface write token
106
  if not civitai_key: civitai_key = os.environ.get("CIVITAI_API_KEY") # default Civitai API key
 
112
  file = download_file(u, civitai_key)
113
  if not Path(file).exists() or not Path(file).is_file(): continue
114
  url = upload_safetensors_to_repo(file, newrepo_id, repo_type, is_private)
115
+ if url:
116
+ urls.append(url)
117
+ if is_info: upload_info_to_repo(u, file, newrepo_id, repo_type, is_private)
118
  progress(1, desc="Processing...")
119
  md = f'### Your repo: [{newrepo_id}]({"https://huggingface.co/datasets/" if repo_type == "dataset" else "https://huggingface.co/"}{newrepo_id})\n'
120
  for u in urls:
 
192
  gr.update(visible=True), gr.update(visible=True)
193
 
194
 
195
+ def get_civitai_json(dl_url: str, is_html: bool=False, image_baseurl: str=""):
196
+ if not image_baseurl: image_baseurl = dl_url
197
+ default = ("", "", "") if is_html else ""
198
+ if "https://civitai.com/api/download/models/" not in dl_url: return default
199
+ user_agent = get_user_agent()
200
+ headers = {'User-Agent': user_agent, 'content-type': 'application/json'}
201
+ base_url = 'https://civitai.com/api/v1/model-versions/'
202
+ params = {}
203
+ session = requests.Session()
204
+ retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
205
+ session.mount("https://", HTTPAdapter(max_retries=retries))
206
+ url = base_url + str(dl_url.split("/")[-1])
207
+ try:
208
+ r = session.get(url, params=params, headers=headers, stream=True, timeout=(3.0, 15))
209
+ if not r.ok: return default
210
+ json = dict(r.json()).copy()
211
+ html = ""
212
+ image = ""
213
+ if "modelId" in json.keys():
214
+ url = f"https://civitai.com/models/{json['modelId']}"
215
+ r = session.get(url, params=params, headers=headers, stream=True, timeout=(3.0, 15))
216
+ if not r.ok: return json, html, image
217
+ html = r.text
218
+ if 'images' in json.keys() and len(json["images"]) != 0:
219
+ url = json["images"][0]["url"]
220
+ r = session.get(url, params=params, headers=headers, stream=True, timeout=(3.0, 15))
221
+ if not r.ok: return json, html, image
222
+ image_temp = str(Path(TEMP_DIR, "image" + Path(url.split("/")[-1]).suffix))
223
+ image = str(Path(TEMP_DIR, Path(image_baseurl.split("/")[-1]).stem + ".png"))
224
+ with open(image_temp, 'wb') as f:
225
+ f.write(r.content)
226
+ Image.open(image_temp).convert('RGBA').save(image)
227
+ return json, html, image
228
+ except Exception as e:
229
+ print(e)
230
+ return default
231
+
232
+
233
  def select_civitai_item(results: list[str]):
234
  if "http" not in "".join(results): return gr.update(value="None", visible=True)
235
  result = civitai_last_results.get(results[-1], "None")
236
  md = result['md'] if result else ""
237
+ json = {}
238
+ #json, html, image = get_civitai_json(results[-1], True) # for debugging
239
+ return gr.update(value=md, visible=True), gr.update(value=json, visible=False)
240
 
241
 
242
  def add_civitai_item(results: list[str], dl_url: str):