John6666 commited on
Commit
efd4b9a
·
verified ·
1 Parent(s): f1eb3d1

Upload 4 files

Browse files
Files changed (4) hide show
  1. app.py +22 -45
  2. lora_dict.json +7 -0
  3. modutils.py +191 -54
  4. null.png +0 -0
app.py CHANGED
@@ -157,34 +157,6 @@ UPSCALER_DICT_GUI = {
157
 
158
  UPSCALER_KEYS = list(UPSCALER_DICT_GUI.keys())
159
 
160
- def download_things(directory, url, hf_token="", civitai_api_key=""):
161
- url = url.strip()
162
- if "drive.google.com" in url:
163
- original_dir = os.getcwd()
164
- os.chdir(directory)
165
- os.system(f"gdown --fuzzy {url}")
166
- os.chdir(original_dir)
167
- elif "huggingface.co" in url:
168
- url = url.replace("?download=true", "")
169
- # url = urllib.parse.quote(url, safe=':/') # fix encoding
170
- if "/blob/" in url:
171
- url = url.replace("/blob/", "/resolve/")
172
- user_header = f'"Authorization: Bearer {hf_token}"'
173
- if hf_token:
174
- os.system(f"aria2c --console-log-level=error --summary-interval=10 --header={user_header} -c -x 16 -k 1M -s 16 {url} -d {directory} -o {url.split('/')[-1]}")
175
- else:
176
- os.system(f"aria2c --optimize-concurrent-downloads --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 {url} -d {directory} -o {url.split('/')[-1]}")
177
- elif "civitai.com" in url:
178
- if "?" in url:
179
- url = url.split("?")[0]
180
- if civitai_api_key:
181
- url = url + f"?token={civitai_api_key}"
182
- os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}")
183
- else:
184
- print("\033[91mYou need an API key to download Civitai models.\033[0m")
185
- else:
186
- os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}")
187
-
188
  def get_model_list(directory_path):
189
  model_list = []
190
  valid_extensions = {'.ckpt', '.pt', '.pth', '.safetensors', '.bin'}
@@ -202,9 +174,10 @@ def get_model_list(directory_path):
202
  from modutils import (list_uniq, download_private_repo, get_model_id_list, get_tupled_embed_list,
203
  get_lora_model_list, get_all_lora_tupled_list, update_loras, apply_lora_prompt, set_prompt_loras,
204
  get_my_lora, upload_file_lora, move_file_lora, search_civitai_lora, select_civitai_lora,
 
205
  set_textual_inversion_prompt, get_model_pipeline, change_interface_mode, get_t2i_model_info,
206
  get_tupled_model_list, save_gallery_images, set_optimization, set_sampler_settings,
207
- set_quick_presets, process_style_prompt, optimization_list, save_images,
208
  preset_styles, preset_quality, preset_sampler_setting, translate_to_en)
209
  from env import (HF_TOKEN, CIVITAI_API_KEY, HF_LORA_ESSENTIAL_PRIVATE_REPO, HF_VAE_PRIVATE_REPO,
210
  HF_SDXL_EMBEDS_NEGATIVE_PRIVATE_REPO, HF_SDXL_EMBEDS_POSITIVE_PRIVATE_REPO,
@@ -880,15 +853,14 @@ CSS ="""
880
  #gallery { flex-grow:1; !important; }
881
  .lora { min-width:480px; !important; }
882
  #model-info { text-align:center; }
 
 
 
883
  """
884
 
885
  with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', elem_id="main", fill_width=True, css=CSS, delete_cache=(60, 3600)) as app:
886
- gr.Markdown("# 🧩 DiffuseCraft Mod")
887
- gr.Markdown(
888
- f"""
889
- This space is a modification of [r3gm's DiffuseCraft](https://huggingface.co/spaces/r3gm/DiffuseCraft).
890
- """
891
- )
892
  with gr.Column():
893
  with gr.Tab("Generation"):
894
  with gr.Row():
@@ -898,7 +870,7 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', elem_id="main", fill_width=True, cs
898
  task_gui = gr.Dropdown(label="Task", choices=SDXL_TASK, value=TASK_MODEL_LIST[0])
899
  with gr.Group():
900
  model_name_gui = gr.Dropdown(label="Model", info="You can enter a huggingface model repo_id to want to use.", choices=get_tupled_model_list(model_list), value="votepurchase/animagine-xl-3.1", allow_custom_value=True)
901
- model_info_gui = gr.Markdown(elem_id="model-info")
902
  with gr.Row():
903
  quick_model_type_gui = gr.Radio(label="Model Type", choices=["None", "Auto", "Animagine", "Pony"], value="Auto", interactive=True)
904
  quick_genre_gui = gr.Radio(label="Genre", choices=["Anime", "Photo"], value="Anime", interactive=True)
@@ -1146,14 +1118,17 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', elem_id="main", fill_width=True, cs
1146
  lora5_desc_gui = gr.Markdown(value="", visible=False)
1147
  with gr.Accordion("From URL", open=True, visible=True):
1148
  with gr.Row():
1149
- search_civitai_basemodel_lora = gr.CheckboxGroup(label="Search LoRA for", choices=["Pony", "SD 1.5", "SDXL 1.0", "Flux.1 D", "Flux.1 S"], value=["Pony", "SDXL 1.0"])
1150
- search_civitai_sort_lora = gr.Radio(label="Sort", choices=["Highest Rated", "Most Downloaded", "Newest"], value="Highest Rated")
1151
- search_civitai_period_lora = gr.Radio(label="Period", choices=["AllTime", "Year", "Month", "Week", "Day"], value="AllTime")
1152
  with gr.Row():
1153
  search_civitai_query_lora = gr.Textbox(label="Query", placeholder="oomuro sakurako...", lines=1)
1154
- search_civitai_tag_lora = gr.Textbox(label="Tag", lines=1)
1155
- search_civitai_button_lora = gr.Button("Search on Civitai")
1156
- search_civitai_desc_lora = gr.Markdown(value="", visible=False)
 
 
 
1157
  search_civitai_result_lora = gr.Dropdown(label="Search Results", choices=[("", "")], value="", allow_custom_value=True, visible=False)
1158
  text_lora = gr.Textbox(label="LoRA URL", placeholder="https://civitai.com/api/download/models/28907", lines=1)
1159
  button_lora = gr.Button("Get and update lists of LoRAs")
@@ -1578,14 +1553,16 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', elem_id="main", fill_width=True, cs
1578
  lora4_copy_gui.click(apply_lora_prompt, [prompt_gui, lora4_info_gui], [prompt_gui], queue=False)
1579
  lora5_copy_gui.click(apply_lora_prompt, [prompt_gui, lora5_info_gui], [prompt_gui], queue=False)
1580
  gr.on(
1581
- triggers=[search_civitai_button_lora.click, search_civitai_query_lora.submit, search_civitai_tag_lora.submit],
1582
  fn=search_civitai_lora,
1583
- inputs=[search_civitai_query_lora, search_civitai_basemodel_lora, search_civitai_sort_lora, search_civitai_period_lora, search_civitai_tag_lora],
1584
- outputs=[search_civitai_result_lora, search_civitai_desc_lora, search_civitai_button_lora, search_civitai_query_lora],
 
1585
  queue=True,
1586
  scroll_to_output=True,
1587
  )
1588
  search_civitai_result_lora.change(select_civitai_lora, [search_civitai_result_lora], [text_lora, search_civitai_desc_lora], queue=False, scroll_to_output=True)
 
1589
  button_lora.click(get_my_lora, [text_lora], [lora1_gui, lora2_gui, lora3_gui, lora4_gui, lora5_gui], scroll_to_output=True)
1590
  upload_button_lora.upload(upload_file_lora, [upload_button_lora], [file_output_lora, upload_button_lora]).success(
1591
  move_file_lora, [file_output_lora], [lora1_gui, lora2_gui, lora3_gui, lora4_gui, lora5_gui], scroll_to_output=True)
 
157
 
158
  UPSCALER_KEYS = list(UPSCALER_DICT_GUI.keys())
159
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  def get_model_list(directory_path):
161
  model_list = []
162
  valid_extensions = {'.ckpt', '.pt', '.pth', '.safetensors', '.bin'}
 
174
  from modutils import (list_uniq, download_private_repo, get_model_id_list, get_tupled_embed_list,
175
  get_lora_model_list, get_all_lora_tupled_list, update_loras, apply_lora_prompt, set_prompt_loras,
176
  get_my_lora, upload_file_lora, move_file_lora, search_civitai_lora, select_civitai_lora,
177
+ update_civitai_selection, get_civitai_tag, CIVITAI_SORT, CIVITAI_PERIOD, CIVITAI_BASEMODEL,
178
  set_textual_inversion_prompt, get_model_pipeline, change_interface_mode, get_t2i_model_info,
179
  get_tupled_model_list, save_gallery_images, set_optimization, set_sampler_settings,
180
+ set_quick_presets, process_style_prompt, optimization_list, save_images, download_things,
181
  preset_styles, preset_quality, preset_sampler_setting, translate_to_en)
182
  from env import (HF_TOKEN, CIVITAI_API_KEY, HF_LORA_ESSENTIAL_PRIVATE_REPO, HF_VAE_PRIVATE_REPO,
183
  HF_SDXL_EMBEDS_NEGATIVE_PRIVATE_REPO, HF_SDXL_EMBEDS_POSITIVE_PRIVATE_REPO,
 
853
  #gallery { flex-grow:1; !important; }
854
  .lora { min-width:480px; !important; }
855
  #model-info { text-align:center; }
856
+ .title { font-size: 3em; align-items: center; text-align: center; }
857
+ .info { align-items: center; text-align: center; }
858
+ .desc [src$='#float'] { float: right; margin: 20px; }
859
  """
860
 
861
  with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', elem_id="main", fill_width=True, css=CSS, delete_cache=(60, 3600)) as app:
862
+ gr.Markdown("# 🧩 DiffuseCraft Mod", elem_classes="title")
863
+ gr.Markdown("This space is a modification of [r3gm's DiffuseCraft](https://huggingface.co/spaces/r3gm/DiffuseCraft).", elem_classes="info")
 
 
 
 
864
  with gr.Column():
865
  with gr.Tab("Generation"):
866
  with gr.Row():
 
870
  task_gui = gr.Dropdown(label="Task", choices=SDXL_TASK, value=TASK_MODEL_LIST[0])
871
  with gr.Group():
872
  model_name_gui = gr.Dropdown(label="Model", info="You can enter a huggingface model repo_id to want to use.", choices=get_tupled_model_list(model_list), value="votepurchase/animagine-xl-3.1", allow_custom_value=True)
873
+ model_info_gui = gr.Markdown(elem_classes="info")
874
  with gr.Row():
875
  quick_model_type_gui = gr.Radio(label="Model Type", choices=["None", "Auto", "Animagine", "Pony"], value="Auto", interactive=True)
876
  quick_genre_gui = gr.Radio(label="Genre", choices=["Anime", "Photo"], value="Anime", interactive=True)
 
1118
  lora5_desc_gui = gr.Markdown(value="", visible=False)
1119
  with gr.Accordion("From URL", open=True, visible=True):
1120
  with gr.Row():
1121
+ search_civitai_basemodel_lora = gr.CheckboxGroup(label="Search LoRA for", choices=CIVITAI_BASEMODEL, value=["Pony", "SDXL 1.0"])
1122
+ search_civitai_sort_lora = gr.Radio(label="Sort", choices=CIVITAI_SORT, value="Highest Rated")
1123
+ search_civitai_period_lora = gr.Radio(label="Period", choices=CIVITAI_PERIOD, value="AllTime")
1124
  with gr.Row():
1125
  search_civitai_query_lora = gr.Textbox(label="Query", placeholder="oomuro sakurako...", lines=1)
1126
+ search_civitai_tag_lora = gr.Dropdown(label="Tag", choices=get_civitai_tag(), value=get_civitai_tag()[0], allow_custom_value=True)
1127
+ search_civitai_user_lora = gr.Textbox(label="Username", lines=1)
1128
+ search_civitai_button_lora = gr.Button("Search on Civitai")
1129
+ search_civitai_desc_lora = gr.Markdown(value="", visible=False, elem_classes="desc")
1130
+ with gr.Accordion("Select from Gallery", open=False):
1131
+ search_civitai_gallery_lora = gr.Gallery([], label="Results", allow_preview=False, columns=5, show_share_button=False, interactive=False)
1132
  search_civitai_result_lora = gr.Dropdown(label="Search Results", choices=[("", "")], value="", allow_custom_value=True, visible=False)
1133
  text_lora = gr.Textbox(label="LoRA URL", placeholder="https://civitai.com/api/download/models/28907", lines=1)
1134
  button_lora = gr.Button("Get and update lists of LoRAs")
 
1553
  lora4_copy_gui.click(apply_lora_prompt, [prompt_gui, lora4_info_gui], [prompt_gui], queue=False)
1554
  lora5_copy_gui.click(apply_lora_prompt, [prompt_gui, lora5_info_gui], [prompt_gui], queue=False)
1555
  gr.on(
1556
+ triggers=[search_civitai_button_lora.click, search_civitai_query_lora.submit],
1557
  fn=search_civitai_lora,
1558
+ inputs=[search_civitai_query_lora, search_civitai_basemodel_lora, search_civitai_sort_lora, search_civitai_period_lora,
1559
+ search_civitai_tag_lora, search_civitai_user_lora, search_civitai_gallery_lora],
1560
+ outputs=[search_civitai_result_lora, search_civitai_desc_lora, search_civitai_button_lora, search_civitai_query_lora, search_civitai_gallery_lora],
1561
  queue=True,
1562
  scroll_to_output=True,
1563
  )
1564
  search_civitai_result_lora.change(select_civitai_lora, [search_civitai_result_lora], [text_lora, search_civitai_desc_lora], queue=False, scroll_to_output=True)
1565
+ search_civitai_gallery_lora.select(update_civitai_selection, None, [search_civitai_result_lora], queue=False, show_api=False)
1566
  button_lora.click(get_my_lora, [text_lora], [lora1_gui, lora2_gui, lora3_gui, lora4_gui, lora5_gui], scroll_to_output=True)
1567
  upload_button_lora.upload(upload_file_lora, [upload_button_lora], [file_output_lora, upload_button_lora]).success(
1568
  move_file_lora, [file_output_lora], [lora1_gui, lora2_gui, lora3_gui, lora4_gui, lora5_gui], scroll_to_output=True)
lora_dict.json CHANGED
@@ -4381,6 +4381,13 @@
4381
  "https://civitai.com/models/577378",
4382
  "https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/459bd20d-a9d6-4a0b-8947-7dcebc061c0f/width=450/19781986.jpeg"
4383
  ],
 
 
 
 
 
 
 
4384
  "genshin_v4": [
4385
  "hina_(genshin_impact) / sethos_(genshin_impact) / raiden_shogun_mitake",
4386
  "Pony",
 
4381
  "https://civitai.com/models/577378",
4382
  "https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/459bd20d-a9d6-4a0b-8947-7dcebc061c0f/width=450/19781986.jpeg"
4383
  ],
4384
+ "genbaneko_v4_illustrious_uo_1024-000040": [
4385
+ "genbaneko / cat, headwear, hat, grey headwear, baseball cap, / speech bubble, speech text,",
4386
+ "SDXL 1.0",
4387
+ "Shigotoneko(Genbaneko) Style - illustrious | \u4ed5\u4e8b\u732b\uff08\u73fe\u5834\u732b\uff09",
4388
+ "https://civitai.com/models/859355",
4389
+ "https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/0f145509-d867-418c-b545-0c0e49275f48/width=450/34849585.jpeg"
4390
+ ],
4391
  "genshin_v4": [
4392
  "hina_(genshin_impact) / sethos_(genshin_impact) / raiden_shogun_mitake",
4393
  "Pony",
modutils.py CHANGED
@@ -1,10 +1,17 @@
1
  import spaces
2
  import json
3
  import gradio as gr
4
- from huggingface_hub import HfApi
5
  import os
 
6
  from pathlib import Path
7
  from PIL import Image
 
 
 
 
 
 
 
8
 
9
 
10
  from env import (HF_LORA_PRIVATE_REPOS1, HF_LORA_PRIVATE_REPOS2,
@@ -36,7 +43,6 @@ def list_sub(a, b):
36
 
37
 
38
  def is_repo_name(s):
39
- import re
40
  return re.fullmatch(r'^[^/]+?/[^/]+?$', s)
41
 
42
 
@@ -61,6 +67,50 @@ def get_local_model_list(dir_path):
61
  return model_list
62
 
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  def download_things(directory, url, hf_token="", civitai_api_key=""):
65
  url = url.strip()
66
  if "drive.google.com" in url:
@@ -73,11 +123,7 @@ def download_things(directory, url, hf_token="", civitai_api_key=""):
73
  # url = urllib.parse.quote(url, safe=':/') # fix encoding
74
  if "/blob/" in url:
75
  url = url.replace("/blob/", "/resolve/")
76
- user_header = f'"Authorization: Bearer {hf_token}"'
77
- if hf_token:
78
- os.system(f"aria2c --console-log-level=error --summary-interval=10 --header={user_header} -c -x 16 -k 1M -s 16 {url} -d {directory} -o {url.split('/')[-1]}")
79
- else:
80
- os.system(f"aria2c --optimize-concurrent-downloads --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 {url} -d {directory} -o {url.split('/')[-1]}")
81
  elif "civitai.com" in url:
82
  if "?" in url:
83
  url = url.split("?")[0]
@@ -90,6 +136,33 @@ def download_things(directory, url, hf_token="", civitai_api_key=""):
90
  os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}")
91
 
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  def escape_lora_basename(basename: str):
94
  return basename.replace(".", "_").replace(" ", "_").replace(",", "")
95
 
@@ -157,7 +230,6 @@ def save_gallery_images(images, progress=gr.Progress(track_tqdm=True)):
157
 
158
 
159
  def download_private_repo(repo_id, dir_path, is_replace):
160
- from huggingface_hub import snapshot_download
161
  if not hf_read_token: return
162
  try:
163
  snapshot_download(repo_id=repo_id, local_dir=dir_path, allow_patterns=['*.ckpt', '*.pt', '*.pth', '*.safetensors', '*.bin'], use_auth_token=hf_read_token)
@@ -196,7 +268,6 @@ def get_private_model_list(repo_id, dir_path):
196
 
197
 
198
  def download_private_file(repo_id, path, is_replace):
199
- from huggingface_hub import hf_hub_download
200
  file = Path(path)
201
  newpath = Path(f'{file.parent.name}/{escape_lora_basename(file.stem)}{file.suffix}') if is_replace else file
202
  if not hf_read_token or newpath.exists(): return
@@ -320,7 +391,9 @@ except Exception as e:
320
  loras_dict = {"None": ["", "", "", "", ""], "": ["", "", "", "", ""]} | private_lora_dict.copy()
321
  civitai_not_exists_list = []
322
  loras_url_to_path_dict = {} # {"URL to download": "local filepath", ...}
323
- civitai_lora_last_results = {} # {"URL to download": {search results}, ...}
 
 
324
  all_lora_list = []
325
 
326
 
@@ -344,9 +417,6 @@ private_lora_model_list = get_private_lora_model_lists()
344
 
345
  def get_civitai_info(path):
346
  global civitai_not_exists_list
347
- import requests
348
- from urllib3.util import Retry
349
- from requests.adapters import HTTPAdapter
350
  if path in set(civitai_not_exists_list): return ["", "", "", "", ""]
351
  if not Path(path).exists(): return None
352
  user_agent = get_user_agent()
@@ -381,7 +451,7 @@ def get_civitai_info(path):
381
 
382
 
383
  def get_lora_model_list():
384
- loras = list_uniq(get_private_lora_model_lists() + get_local_model_list(directory_loras) + DIFFUSERS_FORMAT_LORAS)
385
  loras.insert(0, "None")
386
  loras.insert(0, "")
387
  return loras
@@ -456,7 +526,6 @@ def download_lora(dl_urls: str):
456
 
457
 
458
  def copy_lora(path: str, new_path: str):
459
- import shutil
460
  if path == new_path: return new_path
461
  cpath = Path(path)
462
  npath = Path(new_path)
@@ -520,7 +589,6 @@ def get_valid_lora_path(query: str):
520
 
521
 
522
  def get_valid_lora_wt(prompt: str, lora_path: str, lora_wt: float):
523
- import re
524
  wt = lora_wt
525
  result = re.findall(f'<lora:{to_lora_key(lora_path)}:(.+?)>', prompt)
526
  if not result: return wt
@@ -529,7 +597,6 @@ def get_valid_lora_wt(prompt: str, lora_path: str, lora_wt: float):
529
 
530
 
531
  def set_prompt_loras(prompt, prompt_syntax, model_name, lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt):
532
- import re
533
  if not "Classic" in str(prompt_syntax): return lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt
534
  lora1 = get_valid_lora_name(lora1, model_name)
535
  lora2 = get_valid_lora_name(lora2, model_name)
@@ -649,7 +716,6 @@ def apply_lora_prompt(prompt: str = "", lora_info: str = ""):
649
 
650
 
651
  def update_loras(prompt, prompt_syntax, lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt):
652
- import re
653
  on1, label1, tag1, md1 = get_lora_info(lora1)
654
  on2, label2, tag2, md2 = get_lora_info(lora2)
655
  on3, label3, tag3, md3 = get_lora_info(lora3)
@@ -696,7 +762,6 @@ def update_loras(prompt, prompt_syntax, lora1, lora1_wt, lora2, lora2_wt, lora3,
696
 
697
 
698
  def get_my_lora(link_url):
699
- from pathlib import Path
700
  before = get_local_model_list(directory_loras)
701
  for url in [url.strip() for url in link_url.split(',')]:
702
  if not Path(f"{directory_loras}/{url.split('/')[-1]}").exists():
@@ -733,7 +798,6 @@ def upload_file_lora(files, progress=gr.Progress(track_tqdm=True)):
733
 
734
 
735
  def move_file_lora(filepaths):
736
- import shutil
737
  for file in filepaths:
738
  path = Path(shutil.move(Path(file).resolve(), Path(f"./{directory_loras}").resolve()))
739
  newpath = Path(f'{path.parent.name}/{escape_lora_basename(path.stem)}{path.suffix}')
@@ -756,11 +820,13 @@ def move_file_lora(filepaths):
756
  )
757
 
758
 
 
 
 
 
 
759
  def get_civitai_info(path):
760
  global civitai_not_exists_list, loras_url_to_path_dict
761
- import requests
762
- from requests.adapters import HTTPAdapter
763
- from urllib3.util import Retry
764
  default = ["", "", "", "", ""]
765
  if path in set(civitai_not_exists_list): return default
766
  if not Path(path).exists(): return None
@@ -798,16 +864,14 @@ def get_civitai_info(path):
798
 
799
 
800
  def search_lora_on_civitai(query: str, allow_model: list[str] = ["Pony", "SDXL 1.0"], limit: int = 100,
801
- sort: str = "Highest Rated", period: str = "AllTime", tag: str = ""):
802
- import requests
803
- from requests.adapters import HTTPAdapter
804
- from urllib3.util import Retry
805
  user_agent = get_user_agent()
806
  headers = {'User-Agent': user_agent, 'content-type': 'application/json'}
807
  base_url = 'https://civitai.com/api/v1/models'
808
- params = {'types': ['LORA'], 'sort': sort, 'period': period, 'limit': limit, 'nsfw': 'true'}
809
  if query: params["query"] = query
810
  if tag: params["tag"] = tag
 
811
  session = requests.Session()
812
  retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
813
  session.mount("https://", HTTPAdapter(max_retries=retries))
@@ -824,46 +888,129 @@ def search_lora_on_civitai(query: str, allow_model: list[str] = ["Pony", "SDXL 1
824
  for j in json['items']:
825
  for model in j['modelVersions']:
826
  item = {}
827
- if model['baseModel'] not in set(allow_model): continue
828
  item['name'] = j['name']
829
- item['creator'] = j['creator']['username']
830
- item['tags'] = j['tags']
831
- item['model_name'] = model['name']
832
- item['base_model'] = model['baseModel']
 
833
  item['dl_url'] = model['downloadUrl']
834
- item['md'] = f'<img src="{model["images"][0]["url"]}" alt="thumbnail" width="150" height="240"><br>[LoRA Model URL](https://civitai.com/models/{j["id"]})'
 
 
 
 
 
 
835
  items.append(item)
836
  return items
837
 
838
 
839
- def search_civitai_lora(query, base_model, sort="Highest Rated", period="AllTime", tag=""):
840
- global civitai_lora_last_results
841
- items = search_lora_on_civitai(query, base_model, 100, sort, period, tag)
 
 
 
842
  if not items: return gr.update(choices=[("", "")], value="", visible=False),\
843
- gr.update(value="", visible=False), gr.update(visible=True), gr.update(visible=True)
844
- civitai_lora_last_results = {}
845
  choices = []
 
846
  for item in items:
847
  base_model_name = "Pony🐴" if item['base_model'] == "Pony" else item['base_model']
848
  name = f"{item['name']} (for {base_model_name} / By: {item['creator']} / Tags: {', '.join(item['tags'])})"
849
  value = item['dl_url']
850
  choices.append((name, value))
851
- civitai_lora_last_results[value] = item
 
852
  if not choices: return gr.update(choices=[("", "")], value="", visible=False),\
853
- gr.update(value="", visible=False), gr.update(visible=True), gr.update(visible=True)
854
- result = civitai_lora_last_results.get(choices[0][1], "None")
 
 
855
  md = result['md'] if result else ""
856
  return gr.update(choices=choices, value=choices[0][1], visible=True), gr.update(value=md, visible=True),\
857
- gr.update(visible=True), gr.update(visible=True)
 
 
 
 
 
 
 
 
 
858
 
859
 
860
  def select_civitai_lora(search_result):
861
  if not "http" in search_result: return gr.update(value=""), gr.update(value="None", visible=True)
862
- result = civitai_lora_last_results.get(search_result, "None")
863
  md = result['md'] if result else ""
864
  return gr.update(value=search_result), gr.update(value=md, visible=True)
865
 
866
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
867
  LORA_BASE_MODEL_DICT = {
868
  "diffusers:StableDiffusionPipeline": ["SD 1.5"],
869
  "diffusers:StableDiffusionXLPipeline": ["Pony", "SDXL 1.0"],
@@ -1108,15 +1255,6 @@ preset_quality = {k["name"]: (k["prompt"], k["negative_prompt"]) for k in qualit
1108
 
1109
 
1110
  def process_style_prompt(prompt: str, neg_prompt: str, styles_key: str = "None", quality_key: str = "None", type: str = "Auto"):
1111
- def to_list(s):
1112
- return [x.strip() for x in s.split(",") if not s == ""]
1113
-
1114
- def list_sub(a, b):
1115
- return [e for e in a if e not in b]
1116
-
1117
- def list_uniq(l):
1118
- return sorted(set(l), key=l.index)
1119
-
1120
  animagine_ps = to_list("anime artwork, anime style, vibrant, studio anime, highly detailed, masterpiece, best quality, very aesthetic, absurdres")
1121
  animagine_nps = to_list("lowres, (bad), text, error, fewer, extra, missing, worst quality, jpeg artifacts, low quality, watermark, unfinished, displeasing, oldest, early, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]")
1122
  pony_ps = to_list("source_anime, score_9, score_8_up, score_7_up, masterpiece, best quality, very aesthetic, absurdres")
@@ -1268,7 +1406,6 @@ def set_textual_inversion_prompt(textual_inversion_gui, prompt_gui, neg_prompt_g
1268
 
1269
 
1270
  def get_model_pipeline(repo_id: str):
1271
- from huggingface_hub import HfApi
1272
  api = HfApi(token=HF_TOKEN)
1273
  default = "StableDiffusionPipeline"
1274
  try:
 
1
  import spaces
2
  import json
3
  import gradio as gr
 
4
  import os
5
+ import re
6
  from pathlib import Path
7
  from PIL import Image
8
+ import shutil
9
+ import requests
10
+ from requests.adapters import HTTPAdapter
11
+ from urllib3.util import Retry
12
+ import urllib.parse
13
+ import pandas as pd
14
+ from huggingface_hub import HfApi, HfFolder, hf_hub_download, snapshot_download
15
 
16
 
17
  from env import (HF_LORA_PRIVATE_REPOS1, HF_LORA_PRIVATE_REPOS2,
 
43
 
44
 
45
  def is_repo_name(s):
 
46
  return re.fullmatch(r'^[^/]+?/[^/]+?$', s)
47
 
48
 
 
67
  return model_list
68
 
69
 
70
+ def get_token():
71
+ try:
72
+ token = HfFolder.get_token()
73
+ except Exception:
74
+ token = ""
75
+ return token
76
+
77
+
78
+ def set_token(token):
79
+ try:
80
+ HfFolder.save_token(token)
81
+ except Exception:
82
+ print(f"Error: Failed to save token.")
83
+
84
+
85
+ set_token(HF_TOKEN)
86
+
87
+
88
+ def split_hf_url(url: str):
89
+ try:
90
+ s = list(re.findall(r'^(?:https?://huggingface.co/)(?:(datasets)/)?(.+?/.+?)/\w+?/.+?/(?:(.+)/)?(.+?.\w+)(?:\?download=true)?$', url)[0])
91
+ if len(s) < 4: return "", "", "", ""
92
+ repo_id = s[1]
93
+ repo_type = "dataset" if s[0] == "datasets" else "model"
94
+ subfolder = urllib.parse.unquote(s[2]) if s[2] else None
95
+ filename = urllib.parse.unquote(s[3])
96
+ return repo_id, filename, subfolder, repo_type
97
+ except Exception as e:
98
+ print(e)
99
+
100
+
101
+ def download_hf_file(directory, url, progress=gr.Progress(track_tqdm=True)):
102
+ hf_token = get_token()
103
+ repo_id, filename, subfolder, repo_type = split_hf_url(url)
104
+ try:
105
+ print(f"Downloading {url} to {directory}")
106
+ if subfolder is not None: path = hf_hub_download(repo_id=repo_id, filename=filename, subfolder=subfolder, repo_type=repo_type, local_dir=directory, token=hf_token)
107
+ else: path = hf_hub_download(repo_id=repo_id, filename=filename, repo_type=repo_type, local_dir=directory, token=hf_token)
108
+ return path
109
+ except Exception as e:
110
+ print(f"Failed to download: {e}")
111
+ return None
112
+
113
+
114
  def download_things(directory, url, hf_token="", civitai_api_key=""):
115
  url = url.strip()
116
  if "drive.google.com" in url:
 
123
  # url = urllib.parse.quote(url, safe=':/') # fix encoding
124
  if "/blob/" in url:
125
  url = url.replace("/blob/", "/resolve/")
126
+ download_hf_file(directory, url)
 
 
 
 
127
  elif "civitai.com" in url:
128
  if "?" in url:
129
  url = url.split("?")[0]
 
136
  os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}")
137
 
138
 
139
+ def get_download_file(temp_dir, url, civitai_key="", progress=gr.Progress(track_tqdm=True)):
140
+ if not "http" in url and is_repo_name(url) and not Path(url).exists():
141
+ print(f"Use HF Repo: {url}")
142
+ new_file = url
143
+ elif not "http" in url and Path(url).exists():
144
+ print(f"Use local file: {url}")
145
+ new_file = url
146
+ elif Path(f"{temp_dir}/{url.split('/')[-1]}").exists():
147
+ print(f"File to download alreday exists: {url}")
148
+ new_file = f"{temp_dir}/{url.split('/')[-1]}"
149
+ else:
150
+ print(f"Start downloading: {url}")
151
+ before = get_local_model_list(temp_dir)
152
+ try:
153
+ download_things(temp_dir, url.strip(), HF_TOKEN, civitai_key)
154
+ except Exception:
155
+ print(f"Download failed: {url}")
156
+ return ""
157
+ after = get_local_model_list(temp_dir)
158
+ new_file = list_sub(after, before)[0] if list_sub(after, before) else ""
159
+ if not new_file:
160
+ print(f"Download failed: {url}")
161
+ return ""
162
+ print(f"Download completed: {url}")
163
+ return new_file
164
+
165
+
166
  def escape_lora_basename(basename: str):
167
  return basename.replace(".", "_").replace(" ", "_").replace(",", "")
168
 
 
230
 
231
 
232
  def download_private_repo(repo_id, dir_path, is_replace):
 
233
  if not hf_read_token: return
234
  try:
235
  snapshot_download(repo_id=repo_id, local_dir=dir_path, allow_patterns=['*.ckpt', '*.pt', '*.pth', '*.safetensors', '*.bin'], use_auth_token=hf_read_token)
 
268
 
269
 
270
  def download_private_file(repo_id, path, is_replace):
 
271
  file = Path(path)
272
  newpath = Path(f'{file.parent.name}/{escape_lora_basename(file.stem)}{file.suffix}') if is_replace else file
273
  if not hf_read_token or newpath.exists(): return
 
391
  loras_dict = {"None": ["", "", "", "", ""], "": ["", "", "", "", ""]} | private_lora_dict.copy()
392
  civitai_not_exists_list = []
393
  loras_url_to_path_dict = {} # {"URL to download": "local filepath", ...}
394
+ civitai_last_results = {} # {"URL to download": {search results}, ...}
395
+ civitai_last_choices = [("", "")]
396
+ civitai_last_gallery = []
397
  all_lora_list = []
398
 
399
 
 
417
 
418
  def get_civitai_info(path):
419
  global civitai_not_exists_list
 
 
 
420
  if path in set(civitai_not_exists_list): return ["", "", "", "", ""]
421
  if not Path(path).exists(): return None
422
  user_agent = get_user_agent()
 
451
 
452
 
453
  def get_lora_model_list():
454
+ loras = list_uniq(get_private_lora_model_lists() + DIFFUSERS_FORMAT_LORAS + get_local_model_list(directory_loras))
455
  loras.insert(0, "None")
456
  loras.insert(0, "")
457
  return loras
 
526
 
527
 
528
  def copy_lora(path: str, new_path: str):
 
529
  if path == new_path: return new_path
530
  cpath = Path(path)
531
  npath = Path(new_path)
 
589
 
590
 
591
  def get_valid_lora_wt(prompt: str, lora_path: str, lora_wt: float):
 
592
  wt = lora_wt
593
  result = re.findall(f'<lora:{to_lora_key(lora_path)}:(.+?)>', prompt)
594
  if not result: return wt
 
597
 
598
 
599
  def set_prompt_loras(prompt, prompt_syntax, model_name, lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt):
 
600
  if not "Classic" in str(prompt_syntax): return lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt
601
  lora1 = get_valid_lora_name(lora1, model_name)
602
  lora2 = get_valid_lora_name(lora2, model_name)
 
716
 
717
 
718
  def update_loras(prompt, prompt_syntax, lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt):
 
719
  on1, label1, tag1, md1 = get_lora_info(lora1)
720
  on2, label2, tag2, md2 = get_lora_info(lora2)
721
  on3, label3, tag3, md3 = get_lora_info(lora3)
 
762
 
763
 
764
  def get_my_lora(link_url):
 
765
  before = get_local_model_list(directory_loras)
766
  for url in [url.strip() for url in link_url.split(',')]:
767
  if not Path(f"{directory_loras}/{url.split('/')[-1]}").exists():
 
798
 
799
 
800
  def move_file_lora(filepaths):
 
801
  for file in filepaths:
802
  path = Path(shutil.move(Path(file).resolve(), Path(f"./{directory_loras}").resolve()))
803
  newpath = Path(f'{path.parent.name}/{escape_lora_basename(path.stem)}{path.suffix}')
 
820
  )
821
 
822
 
823
+ CIVITAI_SORT = ["Highest Rated", "Most Downloaded", "Newest"]
824
+ CIVITAI_PERIOD = ["AllTime", "Year", "Month", "Week", "Day"]
825
+ CIVITAI_BASEMODEL = ["Pony", "SD 1.5", "SDXL 1.0", "Flux.1 D", "Flux.1 S"]
826
+
827
+
828
  def get_civitai_info(path):
829
  global civitai_not_exists_list, loras_url_to_path_dict
 
 
 
830
  default = ["", "", "", "", ""]
831
  if path in set(civitai_not_exists_list): return default
832
  if not Path(path).exists(): return None
 
864
 
865
 
866
  def search_lora_on_civitai(query: str, allow_model: list[str] = ["Pony", "SDXL 1.0"], limit: int = 100,
867
+ sort: str = "Highest Rated", period: str = "AllTime", tag: str = "", user: str = "", page: int = 1):
 
 
 
868
  user_agent = get_user_agent()
869
  headers = {'User-Agent': user_agent, 'content-type': 'application/json'}
870
  base_url = 'https://civitai.com/api/v1/models'
871
+ params = {'types': ['LORA'], 'sort': sort, 'period': period, 'limit': limit, 'page': int(page), 'nsfw': 'true'}
872
  if query: params["query"] = query
873
  if tag: params["tag"] = tag
874
+ if user: params["username"] = user
875
  session = requests.Session()
876
  retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
877
  session.mount("https://", HTTPAdapter(max_retries=retries))
 
888
  for j in json['items']:
889
  for model in j['modelVersions']:
890
  item = {}
891
+ if len(allow_model) != 0 and model['baseModel'] not in set(allow_model): continue
892
  item['name'] = j['name']
893
+ item['creator'] = j['creator']['username'] if 'creator' in j.keys() and 'username' in j['creator'].keys() else ""
894
+ item['tags'] = j['tags'] if 'tags' in j.keys() else []
895
+ item['model_name'] = model['name'] if 'name' in model.keys() else ""
896
+ item['base_model'] = model['baseModel'] if 'baseModel' in model.keys() else ""
897
+ item['description'] = model['description'] if 'description' in model.keys() else ""
898
  item['dl_url'] = model['downloadUrl']
899
+ item['md'] = ""
900
+ if 'images' in model.keys() and len(model["images"]) != 0:
901
+ item['img_url'] = model["images"][0]["url"]
902
+ item['md'] += f'<img src="{model["images"][0]["url"]}#float" alt="thumbnail" width="150" height="240"><br>'
903
+ else: item['img_url'] = "/home/user/app/null.png"
904
+ item['md'] += f'''Model URL: [https://civitai.com/models/{j["id"]}](https://civitai.com/models/{j["id"]})<br>Model Name: {item["name"]}<br>
905
+ Creator: {item["creator"]}<br>Tags: {", ".join(item["tags"])}<br>Base Model: {item["base_model"]}<br>Description: {item["description"]}'''
906
  items.append(item)
907
  return items
908
 
909
 
910
+ def search_civitai_lora(query, base_model=[], sort=CIVITAI_SORT[0], period=CIVITAI_PERIOD[0], tag="", user="", gallery=[]):
911
+ global civitai_last_results, civitai_last_choices, civitai_last_gallery
912
+ civitai_last_choices = [("", "")]
913
+ civitai_last_gallery = []
914
+ civitai_last_results = {}
915
+ items = search_lora_on_civitai(query, base_model, 100, sort, period, tag, user)
916
  if not items: return gr.update(choices=[("", "")], value="", visible=False),\
917
+ gr.update(value="", visible=False), gr.update(visible=True), gr.update(visible=True), gr.update(visible=True)
918
+ civitai_last_results = {}
919
  choices = []
920
+ gallery = []
921
  for item in items:
922
  base_model_name = "Pony🐴" if item['base_model'] == "Pony" else item['base_model']
923
  name = f"{item['name']} (for {base_model_name} / By: {item['creator']} / Tags: {', '.join(item['tags'])})"
924
  value = item['dl_url']
925
  choices.append((name, value))
926
+ gallery.append((item['img_url'], name))
927
+ civitai_last_results[value] = item
928
  if not choices: return gr.update(choices=[("", "")], value="", visible=False),\
929
+ gr.update(value="", visible=False), gr.update(visible=True), gr.update(visible=True), gr.update(visible=True)
930
+ civitai_last_choices = choices
931
+ civitai_last_gallery = gallery
932
+ result = civitai_last_results.get(choices[0][1], "None")
933
  md = result['md'] if result else ""
934
  return gr.update(choices=choices, value=choices[0][1], visible=True), gr.update(value=md, visible=True),\
935
+ gr.update(visible=True), gr.update(visible=True), gr.update(value=gallery)
936
+
937
+
938
+ def update_civitai_selection(evt: gr.SelectData):
939
+ try:
940
+ selected_index = evt.index
941
+ selected = civitai_last_choices[selected_index][1]
942
+ return gr.update(value=selected)
943
+ except Exception:
944
+ return gr.update(visible=True)
945
 
946
 
947
  def select_civitai_lora(search_result):
948
  if not "http" in search_result: return gr.update(value=""), gr.update(value="None", visible=True)
949
+ result = civitai_last_results.get(search_result, "None")
950
  md = result['md'] if result else ""
951
  return gr.update(value=search_result), gr.update(value=md, visible=True)
952
 
953
 
954
+ def download_my_lora_flux(dl_urls: str, lora):
955
+ path = download_lora(dl_urls)
956
+ if path: lora = path
957
+ choices = get_all_lora_tupled_list()
958
+ return gr.update(value=lora, choices=choices)
959
+
960
+
961
+ def apply_lora_prompt_flux(lora_info: str):
962
+ if lora_info == "None": return ""
963
+ lora_tag = lora_info.replace("/",",")
964
+ lora_tags = lora_tag.split(",") if str(lora_info) != "None" else []
965
+ lora_prompts = normalize_prompt_list(lora_tags)
966
+ prompt = ", ".join(list_uniq(lora_prompts))
967
+ return prompt
968
+
969
+
970
+ def update_loras_flux(prompt, lora, lora_wt):
971
+ on, label, tag, md = get_lora_info(lora)
972
+ choices = get_all_lora_tupled_list()
973
+ return gr.update(value=prompt), gr.update(value=lora, choices=choices), gr.update(value=lora_wt),\
974
+ gr.update(value=tag, label=label, visible=on), gr.update(value=md, visible=on)
975
+
976
+
977
+ def search_civitai_lora_json(query, base_model):
978
+ results = {}
979
+ items = search_lora_on_civitai(query, base_model)
980
+ if not items: return gr.update(value=results)
981
+ for item in items:
982
+ results[item['dl_url']] = item
983
+ return gr.update(value=results)
984
+
985
+
986
+ def get_civitai_tag():
987
+ default = [""]
988
+ user_agent = get_user_agent()
989
+ headers = {'User-Agent': user_agent, 'content-type': 'application/json'}
990
+ base_url = 'https://civitai.com/api/v1/tags'
991
+ params = {'limit': 200}
992
+ session = requests.Session()
993
+ retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
994
+ session.mount("https://", HTTPAdapter(max_retries=retries))
995
+ url = base_url
996
+ try:
997
+ r = session.get(url, params=params, headers=headers, stream=True, timeout=(3.0, 15))
998
+ if not r.ok: return default
999
+ j = dict(r.json()).copy()
1000
+ if "items" not in j.keys(): return default
1001
+ items = []
1002
+ for item in j["items"]:
1003
+ items.append([str(item.get("name", "")), int(item.get("modelCount", 0))])
1004
+ df = pd.DataFrame(items)
1005
+ df.sort_values(1, ascending=False)
1006
+ tags = df.values.tolist()
1007
+ tags = [""] + [l[0] for l in tags]
1008
+ return tags
1009
+ except Exception as e:
1010
+ print(e)
1011
+ return default
1012
+
1013
+
1014
  LORA_BASE_MODEL_DICT = {
1015
  "diffusers:StableDiffusionPipeline": ["SD 1.5"],
1016
  "diffusers:StableDiffusionXLPipeline": ["Pony", "SDXL 1.0"],
 
1255
 
1256
 
1257
  def process_style_prompt(prompt: str, neg_prompt: str, styles_key: str = "None", quality_key: str = "None", type: str = "Auto"):
 
 
 
 
 
 
 
 
 
1258
  animagine_ps = to_list("anime artwork, anime style, vibrant, studio anime, highly detailed, masterpiece, best quality, very aesthetic, absurdres")
1259
  animagine_nps = to_list("lowres, (bad), text, error, fewer, extra, missing, worst quality, jpeg artifacts, low quality, watermark, unfinished, displeasing, oldest, early, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]")
1260
  pony_ps = to_list("source_anime, score_9, score_8_up, score_7_up, masterpiece, best quality, very aesthetic, absurdres")
 
1406
 
1407
 
1408
  def get_model_pipeline(repo_id: str):
 
1409
  api = HfApi(token=HF_TOKEN)
1410
  default = "StableDiffusionPipeline"
1411
  try:
null.png ADDED