John6666 commited on
Commit
76f1f49
1 Parent(s): 5c2ff93

Upload 4 files

Browse files
Files changed (4) hide show
  1. app.py +24 -24
  2. mod.py +8 -1
  3. modutils.py +118 -50
  4. null.png +0 -0
app.py CHANGED
@@ -20,10 +20,10 @@ from mod import (clear_cache, get_repo_safetensors, is_repo_name, is_repo_exists
20
  description_ui, compose_lora_json, is_valid_lora, fuse_loras, save_image, preprocess_i2i_image,
21
  get_trigger_word, enhance_prompt, set_control_union_image,
22
  get_control_union_mode, set_control_union_mode, get_control_params, translate_to_en)
23
- from flux import (search_civitai_lora, select_civitai_lora, search_civitai_lora_json,
24
- download_my_lora, get_all_lora_tupled_list, apply_lora_prompt,
25
- update_loras)
26
- from modutils import get_t2i_model_info, download_hf_file
27
  from tagger.tagger import predict_tags_wd, compose_prompt_to_copy
28
  from tagger.fl2flux import predict_tags_fl2_flux
29
 
@@ -674,7 +674,8 @@ css = '''
674
  #custom_lora_btn{margin-top: auto;margin-bottom: 11px}
675
  #random_btn{font-size: 300%}
676
  #component-11{align-self: stretch;}
677
- .info {text-align:center; !important}
 
678
  '''
679
  with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', fill_width=True, css=css, delete_cache=(60, 3600)) as app:
680
  with gr.Tab("FLUX LoRA the Explorer"):
@@ -730,14 +731,8 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', fill_width=True, css=css, delete_ca
730
  with gr.Row():
731
  with gr.Column():
732
  selected_info = gr.Markdown("")
733
- gallery = gr.Gallery(
734
- [(item["image"], item["title"]) for item in loras],
735
- label="LoRA Gallery",
736
- allow_preview=False,
737
- columns=5,
738
- elem_id="gallery",
739
- show_share_button=False
740
- )
741
  with gr.Group():
742
  with gr.Row(elem_id="custom_lora_structure"):
743
  custom_lora = gr.Textbox(label="Custom LoRA", info="LoRA Hugging Face path or *.safetensors public URL", placeholder="multimodalart/vintage-ads-flux", scale=3, min_width=150)
@@ -802,15 +797,18 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', fill_width=True, css=css, delete_ca
802
  with gr.Accordion("From URL", open=True, visible=True):
803
  with gr.Row():
804
  lora_search_civitai_basemodel = gr.CheckboxGroup(label="Search LoRA for", choices=["Flux.1 D", "Flux.1 S"], value=["Flux.1 D"])
805
- lora_search_civitai_sort = gr.Radio(label="Sort", choices=["Highest Rated", "Most Downloaded", "Newest"], value="Most Downloaded")
806
- lora_search_civitai_period = gr.Radio(label="Period", choices=["AllTime", "Year", "Month", "Week", "Day"], value="Month")
807
  with gr.Row():
808
  lora_search_civitai_query = gr.Textbox(label="Query", placeholder="flux", lines=1)
809
- lora_search_civitai_tag = gr.Textbox(label="Tag", lines=1)
810
- lora_search_civitai_submit = gr.Button("Search on Civitai")
 
811
  with gr.Row():
812
  lora_search_civitai_json = gr.JSON(value={}, visible=False)
813
- lora_search_civitai_desc = gr.Markdown(value="", visible=False)
 
 
814
  lora_search_civitai_result = gr.Dropdown(label="Search Results", choices=[("", "")], value="", allow_custom_value=True, visible=False)
815
  lora_download_url = gr.Textbox(label="LoRA URL", placeholder="https://civitai.com/api/download/models/28907", lines=1)
816
  with gr.Row():
@@ -901,22 +899,24 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', fill_width=True, css=css, delete_ca
901
  prompt_enhance.click(enhance_prompt, [prompt], [prompt], queue=False, show_api=False)
902
 
903
  gr.on(
904
- triggers=[lora_search_civitai_submit.click, lora_search_civitai_query.submit, lora_search_civitai_tag.submit],
905
  fn=search_civitai_lora,
906
- inputs=[lora_search_civitai_query, lora_search_civitai_basemodel, lora_search_civitai_sort, lora_search_civitai_period, lora_search_civitai_tag],
907
- outputs=[lora_search_civitai_result, lora_search_civitai_desc, lora_search_civitai_submit, lora_search_civitai_query],
 
908
  scroll_to_output=True,
909
  queue=True,
910
  show_api=False,
911
  )
912
  lora_search_civitai_json.change(search_civitai_lora_json, [lora_search_civitai_query, lora_search_civitai_basemodel], [lora_search_civitai_json], queue=True, show_api=True) # fn for api
913
  lora_search_civitai_result.change(select_civitai_lora, [lora_search_civitai_result], [lora_download_url, lora_search_civitai_desc], scroll_to_output=True, queue=False, show_api=False)
 
914
 
915
  for i, l in enumerate(lora_repo):
916
  deselect_lora_button.click(lambda: ("", 1.0), None, [lora_repo[i], lora_wt[i]], queue=False, show_api=False)
917
  gr.on(
918
  triggers=[lora_download[i].click],
919
- fn=download_my_lora,
920
  inputs=[lora_download_url, lora_repo[i]],
921
  outputs=[lora_repo[i]],
922
  scroll_to_output=True,
@@ -925,14 +925,14 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', fill_width=True, css=css, delete_ca
925
  )
926
  gr.on(
927
  triggers=[lora_repo[i].change, lora_wt[i].change],
928
- fn=update_loras,
929
  inputs=[prompt, lora_repo[i], lora_wt[i]],
930
  outputs=[prompt, lora_repo[i], lora_wt[i], lora_info[i], lora_md[i]],
931
  queue=False,
932
  trigger_mode="once",
933
  show_api=False,
934
  ).success(get_repo_safetensors, [lora_repo[i]], [lora_weights[i]], queue=False, show_api=False
935
- ).success(apply_lora_prompt, [lora_info[i]], [lora_trigger[i]], queue=False, show_api=False
936
  ).success(compose_lora_json, [lora_repo_json, lora_num[i], lora_repo[i], lora_wt[i], lora_weights[i], lora_trigger[i]], [lora_repo_json], queue=False, show_api=False)
937
 
938
  for i, m in enumerate(cn_mode):
 
20
  description_ui, compose_lora_json, is_valid_lora, fuse_loras, save_image, preprocess_i2i_image,
21
  get_trigger_word, enhance_prompt, set_control_union_image,
22
  get_control_union_mode, set_control_union_mode, get_control_params, translate_to_en)
23
+ from modutils import (search_civitai_lora, select_civitai_lora, search_civitai_lora_json,
24
+ download_my_lora_flux, get_all_lora_tupled_list, apply_lora_prompt_flux,
25
+ update_loras_flux, update_civitai_selection, get_civitai_tag, CIVITAI_SORT, CIVITAI_PERIOD,
26
+ get_t2i_model_info, download_hf_file)
27
  from tagger.tagger import predict_tags_wd, compose_prompt_to_copy
28
  from tagger.fl2flux import predict_tags_fl2_flux
29
 
 
674
  #custom_lora_btn{margin-top: auto;margin-bottom: 11px}
675
  #random_btn{font-size: 300%}
676
  #component-11{align-self: stretch;}
677
+ .info { align-items: center; text-align: center; }
678
+ .desc [src$='#float'] { float: right; margin: 20px; }
679
  '''
680
  with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', fill_width=True, css=css, delete_cache=(60, 3600)) as app:
681
  with gr.Tab("FLUX LoRA the Explorer"):
 
731
  with gr.Row():
732
  with gr.Column():
733
  selected_info = gr.Markdown("")
734
+ gallery = gr.Gallery([(item["image"], item["title"]) for item in loras], label="LoRA Gallery", allow_preview=False,
735
+ columns=5, elem_id="gallery", show_share_button=False, interactive=False)
 
 
 
 
 
 
736
  with gr.Group():
737
  with gr.Row(elem_id="custom_lora_structure"):
738
  custom_lora = gr.Textbox(label="Custom LoRA", info="LoRA Hugging Face path or *.safetensors public URL", placeholder="multimodalart/vintage-ads-flux", scale=3, min_width=150)
 
797
  with gr.Accordion("From URL", open=True, visible=True):
798
  with gr.Row():
799
  lora_search_civitai_basemodel = gr.CheckboxGroup(label="Search LoRA for", choices=["Flux.1 D", "Flux.1 S"], value=["Flux.1 D"])
800
+ lora_search_civitai_sort = gr.Radio(label="Sort", choices=CIVITAI_SORT, value="Most Downloaded")
801
+ lora_search_civitai_period = gr.Radio(label="Period", choices=CIVITAI_PERIOD, value="Month")
802
  with gr.Row():
803
  lora_search_civitai_query = gr.Textbox(label="Query", placeholder="flux", lines=1)
804
+ lora_search_civitai_tag = gr.Dropdown(label="Tag", choices=get_civitai_tag(), value=get_civitai_tag()[0], allow_custom_value=True)
805
+ lora_search_civitai_user = gr.Textbox(label="Username", lines=1)
806
+ lora_search_civitai_submit = gr.Button("Search on Civitai")
807
  with gr.Row():
808
  lora_search_civitai_json = gr.JSON(value={}, visible=False)
809
+ lora_search_civitai_desc = gr.Markdown(value="", visible=False, elem_classes="desc")
810
+ with gr.Accordion("Select from Gallery", open=False):
811
+ lora_search_civitai_gallery = gr.Gallery([], label="Results", allow_preview=False, columns=5, show_share_button=False, interactive=False)
812
  lora_search_civitai_result = gr.Dropdown(label="Search Results", choices=[("", "")], value="", allow_custom_value=True, visible=False)
813
  lora_download_url = gr.Textbox(label="LoRA URL", placeholder="https://civitai.com/api/download/models/28907", lines=1)
814
  with gr.Row():
 
899
  prompt_enhance.click(enhance_prompt, [prompt], [prompt], queue=False, show_api=False)
900
 
901
  gr.on(
902
+ triggers=[lora_search_civitai_submit.click, lora_search_civitai_query.submit],
903
  fn=search_civitai_lora,
904
+ inputs=[lora_search_civitai_query, lora_search_civitai_basemodel, lora_search_civitai_sort, lora_search_civitai_period,
905
+ lora_search_civitai_tag, lora_search_civitai_user, lora_search_civitai_gallery],
906
+ outputs=[lora_search_civitai_result, lora_search_civitai_desc, lora_search_civitai_submit, lora_search_civitai_query, lora_search_civitai_gallery],
907
  scroll_to_output=True,
908
  queue=True,
909
  show_api=False,
910
  )
911
  lora_search_civitai_json.change(search_civitai_lora_json, [lora_search_civitai_query, lora_search_civitai_basemodel], [lora_search_civitai_json], queue=True, show_api=True) # fn for api
912
  lora_search_civitai_result.change(select_civitai_lora, [lora_search_civitai_result], [lora_download_url, lora_search_civitai_desc], scroll_to_output=True, queue=False, show_api=False)
913
+ lora_search_civitai_gallery.select(update_civitai_selection, None, [lora_search_civitai_result], queue=False, show_api=False)
914
 
915
  for i, l in enumerate(lora_repo):
916
  deselect_lora_button.click(lambda: ("", 1.0), None, [lora_repo[i], lora_wt[i]], queue=False, show_api=False)
917
  gr.on(
918
  triggers=[lora_download[i].click],
919
+ fn=download_my_lora_flux,
920
  inputs=[lora_download_url, lora_repo[i]],
921
  outputs=[lora_repo[i]],
922
  scroll_to_output=True,
 
925
  )
926
  gr.on(
927
  triggers=[lora_repo[i].change, lora_wt[i].change],
928
+ fn=update_loras_flux,
929
  inputs=[prompt, lora_repo[i], lora_wt[i]],
930
  outputs=[prompt, lora_repo[i], lora_wt[i], lora_info[i], lora_md[i]],
931
  queue=False,
932
  trigger_mode="once",
933
  show_api=False,
934
  ).success(get_repo_safetensors, [lora_repo[i]], [lora_weights[i]], queue=False, show_api=False
935
+ ).success(apply_lora_prompt_flux, [lora_info[i]], [lora_trigger[i]], queue=False, show_api=False
936
  ).success(compose_lora_json, [lora_repo_json, lora_num[i], lora_repo[i], lora_wt[i], lora_weights[i], lora_trigger[i]], [lora_repo_json], queue=False, show_api=False)
937
 
938
  for i, m in enumerate(cn_mode):
mod.py CHANGED
@@ -5,7 +5,8 @@ from PIL import Image
5
  from pathlib import Path
6
  import gc
7
  import subprocess
8
- from env import num_cns, model_trigger, HF_TOKEN
 
9
  import os
10
 
11
 
@@ -18,6 +19,12 @@ control_images = [None] * num_cns
18
  control_modes = [-1] * num_cns
19
  control_scales = [0] * num_cns
20
 
 
 
 
 
 
 
21
 
22
  def is_repo_name(s):
23
  import re
 
5
  from pathlib import Path
6
  import gc
7
  import subprocess
8
+ from env import num_cns, model_trigger, HF_TOKEN, CIVITAI_API_KEY, download_lora_list, directory_loras
9
+ from modutils import download_things
10
  import os
11
 
12
 
 
19
  control_modes = [-1] * num_cns
20
  control_scales = [0] * num_cns
21
 
22
+ # Download stuffs
23
+ download_lora = ", ".join(download_lora_list)
24
+ for url in [url.strip() for url in download_lora.split(',')]:
25
+ if not os.path.exists(f"./loras/{url.split('/')[-1]}"):
26
+ download_things(directory_loras, url, HF_TOKEN, CIVITAI_API_KEY)
27
+
28
 
29
  def is_repo_name(s):
30
  import re
modutils.py CHANGED
@@ -2,11 +2,16 @@ import spaces
2
  import json
3
  import gradio as gr
4
  import os
 
5
  from pathlib import Path
6
  from PIL import Image
7
- from huggingface_hub import HfApi, HfFolder, hf_hub_download, snapshot_download
 
 
 
8
  import urllib.parse
9
- import re
 
10
 
11
 
12
  from env import (HF_LORA_PRIVATE_REPOS1, HF_LORA_PRIVATE_REPOS2,
@@ -38,7 +43,6 @@ def list_sub(a, b):
38
 
39
 
40
  def is_repo_name(s):
41
- import re
42
  return re.fullmatch(r'^[^/]+?/[^/]+?$', s)
43
 
44
 
@@ -226,7 +230,6 @@ def save_gallery_images(images, progress=gr.Progress(track_tqdm=True)):
226
 
227
 
228
  def download_private_repo(repo_id, dir_path, is_replace):
229
- from huggingface_hub import snapshot_download
230
  if not hf_read_token: return
231
  try:
232
  snapshot_download(repo_id=repo_id, local_dir=dir_path, allow_patterns=['*.ckpt', '*.pt', '*.pth', '*.safetensors', '*.bin'], use_auth_token=hf_read_token)
@@ -265,7 +268,6 @@ def get_private_model_list(repo_id, dir_path):
265
 
266
 
267
  def download_private_file(repo_id, path, is_replace):
268
- from huggingface_hub import hf_hub_download
269
  file = Path(path)
270
  newpath = Path(f'{file.parent.name}/{escape_lora_basename(file.stem)}{file.suffix}') if is_replace else file
271
  if not hf_read_token or newpath.exists(): return
@@ -389,7 +391,9 @@ except Exception as e:
389
  loras_dict = {"None": ["", "", "", "", ""], "": ["", "", "", "", ""]} | private_lora_dict.copy()
390
  civitai_not_exists_list = []
391
  loras_url_to_path_dict = {} # {"URL to download": "local filepath", ...}
392
- civitai_lora_last_results = {} # {"URL to download": {search results}, ...}
 
 
393
  all_lora_list = []
394
 
395
 
@@ -413,9 +417,6 @@ private_lora_model_list = get_private_lora_model_lists()
413
 
414
  def get_civitai_info(path):
415
  global civitai_not_exists_list
416
- import requests
417
- from urllib3.util import Retry
418
- from requests.adapters import HTTPAdapter
419
  if path in set(civitai_not_exists_list): return ["", "", "", "", ""]
420
  if not Path(path).exists(): return None
421
  user_agent = get_user_agent()
@@ -450,7 +451,7 @@ def get_civitai_info(path):
450
 
451
 
452
  def get_lora_model_list():
453
- loras = list_uniq(get_private_lora_model_lists() + get_local_model_list(directory_loras) + DIFFUSERS_FORMAT_LORAS)
454
  loras.insert(0, "None")
455
  loras.insert(0, "")
456
  return loras
@@ -525,7 +526,6 @@ def download_lora(dl_urls: str):
525
 
526
 
527
  def copy_lora(path: str, new_path: str):
528
- import shutil
529
  if path == new_path: return new_path
530
  cpath = Path(path)
531
  npath = Path(new_path)
@@ -589,7 +589,6 @@ def get_valid_lora_path(query: str):
589
 
590
 
591
  def get_valid_lora_wt(prompt: str, lora_path: str, lora_wt: float):
592
- import re
593
  wt = lora_wt
594
  result = re.findall(f'<lora:{to_lora_key(lora_path)}:(.+?)>', prompt)
595
  if not result: return wt
@@ -598,7 +597,6 @@ def get_valid_lora_wt(prompt: str, lora_path: str, lora_wt: float):
598
 
599
 
600
  def set_prompt_loras(prompt, prompt_syntax, model_name, lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt):
601
- import re
602
  if not "Classic" in str(prompt_syntax): return lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt
603
  lora1 = get_valid_lora_name(lora1, model_name)
604
  lora2 = get_valid_lora_name(lora2, model_name)
@@ -718,7 +716,6 @@ def apply_lora_prompt(prompt: str = "", lora_info: str = ""):
718
 
719
 
720
  def update_loras(prompt, prompt_syntax, lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt):
721
- import re
722
  on1, label1, tag1, md1 = get_lora_info(lora1)
723
  on2, label2, tag2, md2 = get_lora_info(lora2)
724
  on3, label3, tag3, md3 = get_lora_info(lora3)
@@ -765,7 +762,6 @@ def update_loras(prompt, prompt_syntax, lora1, lora1_wt, lora2, lora2_wt, lora3,
765
 
766
 
767
  def get_my_lora(link_url):
768
- from pathlib import Path
769
  before = get_local_model_list(directory_loras)
770
  for url in [url.strip() for url in link_url.split(',')]:
771
  if not Path(f"{directory_loras}/{url.split('/')[-1]}").exists():
@@ -802,7 +798,6 @@ def upload_file_lora(files, progress=gr.Progress(track_tqdm=True)):
802
 
803
 
804
  def move_file_lora(filepaths):
805
- import shutil
806
  for file in filepaths:
807
  path = Path(shutil.move(Path(file).resolve(), Path(f"./{directory_loras}").resolve()))
808
  newpath = Path(f'{path.parent.name}/{escape_lora_basename(path.stem)}{path.suffix}')
@@ -825,11 +820,13 @@ def move_file_lora(filepaths):
825
  )
826
 
827
 
 
 
 
 
 
828
  def get_civitai_info(path):
829
  global civitai_not_exists_list, loras_url_to_path_dict
830
- import requests
831
- from requests.adapters import HTTPAdapter
832
- from urllib3.util import Retry
833
  default = ["", "", "", "", ""]
834
  if path in set(civitai_not_exists_list): return default
835
  if not Path(path).exists(): return None
@@ -867,16 +864,14 @@ def get_civitai_info(path):
867
 
868
 
869
  def search_lora_on_civitai(query: str, allow_model: list[str] = ["Pony", "SDXL 1.0"], limit: int = 100,
870
- sort: str = "Highest Rated", period: str = "AllTime", tag: str = ""):
871
- import requests
872
- from requests.adapters import HTTPAdapter
873
- from urllib3.util import Retry
874
  user_agent = get_user_agent()
875
  headers = {'User-Agent': user_agent, 'content-type': 'application/json'}
876
  base_url = 'https://civitai.com/api/v1/models'
877
- params = {'types': ['LORA'], 'sort': sort, 'period': period, 'limit': limit, 'nsfw': 'true'}
878
  if query: params["query"] = query
879
  if tag: params["tag"] = tag
 
880
  session = requests.Session()
881
  retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
882
  session.mount("https://", HTTPAdapter(max_retries=retries))
@@ -893,46 +888,129 @@ def search_lora_on_civitai(query: str, allow_model: list[str] = ["Pony", "SDXL 1
893
  for j in json['items']:
894
  for model in j['modelVersions']:
895
  item = {}
896
- if model['baseModel'] not in set(allow_model): continue
897
  item['name'] = j['name']
898
- item['creator'] = j['creator']['username']
899
- item['tags'] = j['tags']
900
- item['model_name'] = model['name']
901
- item['base_model'] = model['baseModel']
 
902
  item['dl_url'] = model['downloadUrl']
903
- 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"]})'
 
 
 
 
 
 
904
  items.append(item)
905
  return items
906
 
907
 
908
- def search_civitai_lora(query, base_model, sort="Highest Rated", period="AllTime", tag=""):
909
- global civitai_lora_last_results
910
- items = search_lora_on_civitai(query, base_model, 100, sort, period, tag)
 
 
 
911
  if not items: return gr.update(choices=[("", "")], value="", visible=False),\
912
- gr.update(value="", visible=False), gr.update(visible=True), gr.update(visible=True)
913
- civitai_lora_last_results = {}
914
  choices = []
 
915
  for item in items:
916
  base_model_name = "Pony🐴" if item['base_model'] == "Pony" else item['base_model']
917
  name = f"{item['name']} (for {base_model_name} / By: {item['creator']} / Tags: {', '.join(item['tags'])})"
918
  value = item['dl_url']
919
  choices.append((name, value))
920
- civitai_lora_last_results[value] = item
 
921
  if not choices: return gr.update(choices=[("", "")], value="", visible=False),\
922
- gr.update(value="", visible=False), gr.update(visible=True), gr.update(visible=True)
923
- result = civitai_lora_last_results.get(choices[0][1], "None")
 
 
924
  md = result['md'] if result else ""
925
  return gr.update(choices=choices, value=choices[0][1], visible=True), gr.update(value=md, visible=True),\
926
- gr.update(visible=True), gr.update(visible=True)
 
 
 
 
 
 
 
 
 
927
 
928
 
929
  def select_civitai_lora(search_result):
930
  if not "http" in search_result: return gr.update(value=""), gr.update(value="None", visible=True)
931
- result = civitai_lora_last_results.get(search_result, "None")
932
  md = result['md'] if result else ""
933
  return gr.update(value=search_result), gr.update(value=md, visible=True)
934
 
935
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
936
  LORA_BASE_MODEL_DICT = {
937
  "diffusers:StableDiffusionPipeline": ["SD 1.5"],
938
  "diffusers:StableDiffusionXLPipeline": ["Pony", "SDXL 1.0"],
@@ -1177,15 +1255,6 @@ preset_quality = {k["name"]: (k["prompt"], k["negative_prompt"]) for k in qualit
1177
 
1178
 
1179
  def process_style_prompt(prompt: str, neg_prompt: str, styles_key: str = "None", quality_key: str = "None", type: str = "Auto"):
1180
- def to_list(s):
1181
- return [x.strip() for x in s.split(",") if not s == ""]
1182
-
1183
- def list_sub(a, b):
1184
- return [e for e in a if e not in b]
1185
-
1186
- def list_uniq(l):
1187
- return sorted(set(l), key=l.index)
1188
-
1189
  animagine_ps = to_list("anime artwork, anime style, vibrant, studio anime, highly detailed, masterpiece, best quality, very aesthetic, absurdres")
1190
  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]")
1191
  pony_ps = to_list("source_anime, score_9, score_8_up, score_7_up, masterpiece, best quality, very aesthetic, absurdres")
@@ -1337,7 +1406,6 @@ def set_textual_inversion_prompt(textual_inversion_gui, prompt_gui, neg_prompt_g
1337
 
1338
 
1339
  def get_model_pipeline(repo_id: str):
1340
- from huggingface_hub import HfApi
1341
  api = HfApi(token=HF_TOKEN)
1342
  default = "StableDiffusionPipeline"
1343
  try:
 
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
 
 
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