John6666 commited on
Commit
782be4f
1 Parent(s): 80368d1

Upload 7 files

Browse files
Files changed (3) hide show
  1. app.py +2 -2
  2. civitai_to_hf.py +21 -5
  3. utils.py +49 -12
app.py CHANGED
@@ -21,7 +21,7 @@ with gr.Blocks(theme="NoCrypt/miku@>=1.2.2", fill_width=True, css=css, delete_ca
21
  search_civitai_period = gr.Radio(label="Period", choices=CIVITAI_PERIOD, value="Month")
22
  search_civitai_limit = gr.Slider(label="Limit", minimum=1, maximum=100, step=1, value=100)
23
  search_civitai_page = gr.Slider(label="Page", minimum=1, maximum=100, step=1, value=1)
24
- with gr.Row():
25
  search_civitai_query = gr.Textbox(label="Query", placeholder="flux", lines=1)
26
  search_civitai_tag = gr.Dropdown(label="Tag", choices=get_civitai_tag(), value=get_civitai_tag()[0], allow_custom_value=True)
27
  search_civitai_user = gr.Textbox(label="Username", lines=1)
@@ -30,7 +30,7 @@ with gr.Blocks(theme="NoCrypt/miku@>=1.2.2", fill_width=True, css=css, delete_ca
30
  with gr.Row():
31
  search_civitai_desc = gr.Markdown(value="", visible=False, elem_classes="desc")
32
  search_civitai_json = gr.JSON(value={}, visible=False)
33
- with gr.Row():
34
  with gr.Column(scale=9):
35
  with gr.Accordion("Select from Gallery", open=False):
36
  search_civitai_gallery = gr.Gallery([], label="Results", allow_preview=False, columns=5, elem_id="gallery", show_share_button=False, interactive=False)
 
21
  search_civitai_period = gr.Radio(label="Period", choices=CIVITAI_PERIOD, value="Month")
22
  search_civitai_limit = gr.Slider(label="Limit", minimum=1, maximum=100, step=1, value=100)
23
  search_civitai_page = gr.Slider(label="Page", minimum=1, maximum=100, step=1, value=1)
24
+ with gr.Row(equal_height=True):
25
  search_civitai_query = gr.Textbox(label="Query", placeholder="flux", lines=1)
26
  search_civitai_tag = gr.Dropdown(label="Tag", choices=get_civitai_tag(), value=get_civitai_tag()[0], allow_custom_value=True)
27
  search_civitai_user = gr.Textbox(label="Username", lines=1)
 
30
  with gr.Row():
31
  search_civitai_desc = gr.Markdown(value="", visible=False, elem_classes="desc")
32
  search_civitai_json = gr.JSON(value={}, visible=False)
33
+ with gr.Row(equal_height=True):
34
  with gr.Column(scale=9):
35
  with gr.Accordion("Select from Gallery", open=False):
36
  search_civitai_gallery = gr.Gallery([], label="Results", allow_preview=False, columns=5, elem_id="gallery", show_share_button=False, interactive=False)
civitai_to_hf.py CHANGED
@@ -6,14 +6,15 @@ import gc
6
  import requests
7
  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
  from PIL import Image
12
  import json
13
  import pandas as pd
 
14
 
15
 
16
- TEMP_DIR = "."
17
 
18
 
19
  def parse_urls(s):
@@ -25,12 +26,22 @@ def parse_urls(s):
25
  return []
26
 
27
 
 
 
 
 
 
 
 
 
 
 
28
  def to_urls(l: list[str]):
29
  return "\n".join(l)
30
 
31
 
32
  def uniq_urls(s):
33
- return to_urls(list_uniq(parse_urls(s)))
34
 
35
 
36
  def upload_safetensors_to_repo(filename, repo_id, repo_type, is_private, progress=gr.Progress(track_tqdm=True)):
@@ -107,8 +118,8 @@ def download_civitai(dl_url, civitai_key, hf_token, urls,
107
  if not civitai_key: civitai_key = os.environ.get("CIVITAI_API_KEY") # default Civitai API key
108
  if not newrepo_id: newrepo_id = os.environ.get("HF_REPO") # default repo to upload
109
  if not get_token() or not civitai_key: raise gr.Error("HF write token and Civitai API key is required.")
110
- dl_urls = parse_urls(dl_url)
111
  if not urls: urls = []
 
112
  for u in dl_urls:
113
  file = download_file(u, civitai_key)
114
  if not Path(file).exists() or not Path(file).is_file(): continue
@@ -116,6 +127,10 @@ def download_civitai(dl_url, civitai_key, hf_token, urls,
116
  if url:
117
  urls.append(url)
118
  if is_info: upload_info_to_repo(u, file, newrepo_id, repo_type, is_private)
 
 
 
 
119
  progress(1, desc="Processing...")
120
  md = f'### Your repo: [{newrepo_id}]({"https://huggingface.co/datasets/" if repo_type == "dataset" else "https://huggingface.co/"}{newrepo_id})\n'
121
  for u in urls:
@@ -131,7 +146,7 @@ CIVITAI_PERIOD = ["AllTime", "Year", "Month", "Week", "Day"]
131
 
132
 
133
  def search_on_civitai(query: str, types: list[str], allow_model: list[str] = [], limit: int = 100,
134
- sort: str = "Highest Rated", period: str = "AllTime", tag: str = "", user: str = "", page: int = 1):
135
  user_agent = get_user_agent()
136
  headers = {'User-Agent': user_agent, 'content-type': 'application/json'}
137
  base_url = 'https://civitai.com/api/v1/models'
@@ -179,6 +194,7 @@ civitai_last_results = {}
179
  civitai_last_choices = [("", "")]
180
  civitai_last_gallery = []
181
 
 
182
  def search_civitai(query, types, base_model=[], sort=CIVITAI_SORT[0], period=CIVITAI_PERIOD[0], tag="", user="", limit=100, page=1, gallery=[]):
183
  global civitai_last_results, civitai_last_choices, civitai_last_gallery
184
  civitai_last_choices = [("", "")]
 
6
  import requests
7
  from requests.adapters import HTTPAdapter
8
  from urllib3.util import Retry
9
+ from utils import get_token, set_token, is_repo_name, is_repo_exists, get_user_agent, get_download_file, list_uniq, duplicate_hf_repo, HF_SUBFOLDER_NAME
10
  import re
11
  from PIL import Image
12
  import json
13
  import pandas as pd
14
+ import tempfile
15
 
16
 
17
+ TEMP_DIR = tempfile.mkdtemp()
18
 
19
 
20
  def parse_urls(s):
 
26
  return []
27
 
28
 
29
+ def parse_repos(s):
30
+ repo_pattern = r'[^\w_\-\.]?([\w_\-\.]+/[\w_\-\.]+)[^\w_\-\.]?'
31
+ try:
32
+ s = re.sub("https?://[\\w/:%#\\$&\\?\\(\\)~\\.=\\+\\-]+", "", s)
33
+ repos = re.findall(repo_pattern, s)
34
+ return list(repos)
35
+ except Exception:
36
+ return []
37
+
38
+
39
  def to_urls(l: list[str]):
40
  return "\n".join(l)
41
 
42
 
43
  def uniq_urls(s):
44
+ return to_urls(list_uniq(parse_urls(s) + parse_repos(s)))
45
 
46
 
47
  def upload_safetensors_to_repo(filename, repo_id, repo_type, is_private, progress=gr.Progress(track_tqdm=True)):
 
118
  if not civitai_key: civitai_key = os.environ.get("CIVITAI_API_KEY") # default Civitai API key
119
  if not newrepo_id: newrepo_id = os.environ.get("HF_REPO") # default repo to upload
120
  if not get_token() or not civitai_key: raise gr.Error("HF write token and Civitai API key is required.")
 
121
  if not urls: urls = []
122
+ dl_urls = parse_urls(dl_url)
123
  for u in dl_urls:
124
  file = download_file(u, civitai_key)
125
  if not Path(file).exists() or not Path(file).is_file(): continue
 
127
  if url:
128
  urls.append(url)
129
  if is_info: upload_info_to_repo(u, file, newrepo_id, repo_type, is_private)
130
+ dp_repos = parse_repos(dl_url)
131
+ for r in dp_repos:
132
+ url = duplicate_hf_repo(r, newrepo_id, "model", repo_type, is_private, HF_SUBFOLDER_NAME[1])
133
+ if url: urls.append(url)
134
  progress(1, desc="Processing...")
135
  md = f'### Your repo: [{newrepo_id}]({"https://huggingface.co/datasets/" if repo_type == "dataset" else "https://huggingface.co/"}{newrepo_id})\n'
136
  for u in urls:
 
146
 
147
 
148
  def search_on_civitai(query: str, types: list[str], allow_model: list[str] = [], limit: int = 100,
149
+ sort: str = "Highest Rated", period: str = "AllTime", tag: str = "", user: str = "", page: int = 1):
150
  user_agent = get_user_agent()
151
  headers = {'User-Agent': user_agent, 'content-type': 'application/json'}
152
  base_url = 'https://civitai.com/api/v1/models'
 
194
  civitai_last_choices = [("", "")]
195
  civitai_last_gallery = []
196
 
197
+
198
  def search_civitai(query, types, base_model=[], sort=CIVITAI_SORT[0], period=CIVITAI_PERIOD[0], tag="", user="", limit=100, page=1, gallery=[]):
199
  global civitai_last_results, civitai_last_choices, civitai_last_gallery
200
  civitai_last_choices = [("", "")]
utils.py CHANGED
@@ -72,15 +72,24 @@ def list_sub(a, b):
72
 
73
 
74
  def is_repo_name(s):
75
- return re.fullmatch(r'^[^/,\s\"\']+/[^/,\s\"\']+$', s)
 
 
 
 
 
 
 
76
 
77
 
78
  def split_hf_url(url: str):
79
  try:
80
- s = list(re.findall(r'^(?:https?://huggingface.co/)(?:(datasets)/)?(.+?/.+?)/\w+?/.+?/(?:(.+)/)?(.+?.\w+)(?:\?download=true)?$', url)[0])
81
  if len(s) < 4: return "", "", "", ""
82
  repo_id = s[1]
83
- repo_type = "dataset" if s[0] == "datasets" else "model"
 
 
84
  subfolder = urllib.parse.unquote(s[2]) if s[2] else None
85
  filename = urllib.parse.unquote(s[3])
86
  return repo_id, filename, subfolder, repo_type
@@ -160,8 +169,7 @@ def get_download_file(temp_dir, url, civitai_key, progress=gr.Progress(track_tqd
160
  return new_file
161
 
162
 
163
- # https://huggingface.co/docs/huggingface_hub/v0.25.1/en/package_reference/file_download#huggingface_hub.snapshot_download
164
- def download_repo(repo_id, dir_path, progress=gr.Progress(track_tqdm=True)):
165
  hf_token = get_token()
166
  try:
167
  snapshot_download(repo_id=repo_id, local_dir=dir_path, token=hf_token, allow_patterns=["*.safetensors", "*.bin"],
@@ -173,20 +181,49 @@ def download_repo(repo_id, dir_path, progress=gr.Progress(track_tqdm=True)):
173
  return False
174
 
175
 
176
- def upload_repo(new_repo_id, dir_path, is_private, progress=gr.Progress(track_tqdm=True)):
177
  hf_token = get_token()
178
  api = HfApi(token=hf_token)
179
  try:
180
  progress(0, desc="Start uploading...")
181
- api.create_repo(repo_id=new_repo_id, token=hf_token, private=is_private, exist_ok=True)
182
  for path in Path(dir_path).glob("*"):
183
  if path.is_dir():
184
- api.upload_folder(repo_id=new_repo_id, folder_path=str(path), path_in_repo=path.name, token=hf_token)
185
  elif path.is_file():
186
- api.upload_file(repo_id=new_repo_id, path_or_fileobj=str(path), path_in_repo=path.name, token=hf_token)
187
  progress(1, desc="Uploaded.")
188
- url = f"https://huggingface.co/{new_repo_id}"
189
  except Exception as e:
190
- print(f"Error: Failed to upload to {new_repo_id}. {e}")
191
  return ""
192
- return url
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
 
74
  def is_repo_name(s):
75
+ return re.fullmatch(r'^[\w_\-\.]+/[\w_\-\.]+$', s)
76
+
77
+
78
+ def get_hf_url(repo_id: str, repo_type: str="model"):
79
+ if repo_type == "dataset": url = f"https://huggingface.co/datasets/{repo_id}"
80
+ elif repo_type == "space": url = f"https://huggingface.co/spaces/{repo_id}"
81
+ else: url = f"https://huggingface.co/{repo_id}"
82
+ return url
83
 
84
 
85
  def split_hf_url(url: str):
86
  try:
87
+ s = list(re.findall(r'^(?:https?://huggingface.co/)(?:(datasets|spaces)/)?(.+?/.+?)/\w+?/.+?/(?:(.+)/)?(.+?.\w+)(?:\?download=true)?$', url)[0])
88
  if len(s) < 4: return "", "", "", ""
89
  repo_id = s[1]
90
+ if s[0] == "datasets": repo_type = "dataset"
91
+ elif s[0] == "spaces": repo_type = "space"
92
+ else: repo_type = "model"
93
  subfolder = urllib.parse.unquote(s[2]) if s[2] else None
94
  filename = urllib.parse.unquote(s[3])
95
  return repo_id, filename, subfolder, repo_type
 
169
  return new_file
170
 
171
 
172
+ def download_repo(repo_id: str, dir_path: str, progress=gr.Progress(track_tqdm=True)): # for diffusers repo
 
173
  hf_token = get_token()
174
  try:
175
  snapshot_download(repo_id=repo_id, local_dir=dir_path, token=hf_token, allow_patterns=["*.safetensors", "*.bin"],
 
181
  return False
182
 
183
 
184
+ def upload_repo(repo_id: str, dir_path: str, is_private: bool, progress=gr.Progress(track_tqdm=True)): # for diffusers repo
185
  hf_token = get_token()
186
  api = HfApi(token=hf_token)
187
  try:
188
  progress(0, desc="Start uploading...")
189
+ api.create_repo(repo_id=repo_id, token=hf_token, private=is_private, exist_ok=True)
190
  for path in Path(dir_path).glob("*"):
191
  if path.is_dir():
192
+ api.upload_folder(repo_id=repo_id, folder_path=str(path), path_in_repo=path.name, token=hf_token)
193
  elif path.is_file():
194
+ api.upload_file(repo_id=repo_id, path_or_fileobj=str(path), path_in_repo=path.name, token=hf_token)
195
  progress(1, desc="Uploaded.")
196
+ return get_hf_url(repo_id, "model")
197
  except Exception as e:
198
+ print(f"Error: Failed to upload to {repo_id}. {e}")
199
  return ""
200
+
201
+
202
+ HF_SUBFOLDER_NAME = ["None", "user_repo"]
203
+
204
+
205
+ def duplicate_hf_repo(src_repo: str, dst_repo: str, src_repo_type: str, dst_repo_type: str,
206
+ is_private: bool, subfolder_type: str=HF_SUBFOLDER_NAME[1], progress=gr.Progress(track_tqdm=True)):
207
+ hf_token = get_token()
208
+ api = HfApi(token=hf_token)
209
+ try:
210
+ if subfolder_type == "user_repo": subfolder = src_repo.replace("/", "_")
211
+ else: subfolder = ""
212
+ progress(0, desc="Start duplicating...")
213
+ api.create_repo(repo_id=dst_repo, repo_type=dst_repo_type, private=is_private, exist_ok=True, token=hf_token)
214
+ for path in api.list_repo_files(repo_id=src_repo, repo_type=src_repo_type, token=hf_token):
215
+ file = hf_hub_download(repo_id=src_repo, filename=path, repo_type=src_repo_type, token=hf_token)
216
+ if not Path(file).exists(): continue
217
+ if Path(file).is_dir(): # unused for now
218
+ api.upload_folder(repo_id=dst_repo, folder_path=file, path_in_repo=f"{subfolder}/{path}" if subfolder else path,
219
+ repo_type=dst_repo_type, token=hf_token)
220
+ elif Path(file).is_file():
221
+ api.upload_file(repo_id=dst_repo, path_or_fileobj=file, path_in_repo=f"{subfolder}/{path}" if subfolder else path,
222
+ repo_type=dst_repo_type, token=hf_token)
223
+ if Path(file).exists(): Path(file).unlink()
224
+ progress(1, desc="Duplicated.")
225
+ return f"{get_hf_url(dst_repo, dst_repo_type)}/tree/main/{subfolder}" if subfolder else get_hf_url(dst_repo, dst_repo_type)
226
+ except Exception as e:
227
+ print(f"Error: Failed to duplicate repo {src_repo} to {dst_repo}. {e}")
228
+ return ""
229
+