diff --git a/README.md b/README.md
index 7582681..22491a5 100644
--- a/README.md
+++ b/README.md
@@ -100,6 +100,12 @@ https://github.com/BlafKing/sd-civitai-browser-plus/assets/9644716/44c5c7a0-4854
# Changelog 📋
+
v3.5.0
+
+* Bug fix: Extension now works again with the latest CivitAI API version!
+* Cleanup: Re-wrote backend API handling code.
+
+---
v3.4.3
* Bug fix: Hotfix for a change in the public API which broke searching.
diff --git a/javascript/civitai-html.js b/javascript/civitai-html.js
index 243a2f0..f24a283 100644
--- a/javascript/civitai-html.js
+++ b/javascript/civitai-html.js
@@ -223,15 +223,12 @@ function pressRefresh() {
return;
}
-
- let button = document.querySelector("#refreshBtn");
- if (!button) {
- button = document.querySelector("#refreshBtnL");
- }
- if (button) {
- button.click();
- } else {
- console.error("Both buttons with IDs #refreshBtn and #refreshBtnL not found.");
+ let output = gradioApp().querySelector('#page_slider_trigger textarea');
+ if (output) {
+ const randomNumber = Math.floor(Math.random() * 1000);
+ const paddedNumber = String(randomNumber).padStart(3, '0');
+ output.value = paddedNumber;
+ updateInput(output);
}
}, 200);
}
diff --git a/scripts/civitai_api.py b/scripts/civitai_api.py
index e10f39c..53d445b 100644
--- a/scripts/civitai_api.py
+++ b/scripts/civitai_api.py
@@ -138,79 +138,6 @@ def contenttype_folder(content_type, desc=None, fromCheck=False, custom_folder=N
return folder
-def api_to_data(content_type, sort_type, period_type, use_search_term, current_page, base_filter, only_liked, tile_count, search_term=None, nsfw=None, timeOut=None, isNext=None, inputs_changed=None):
- if current_page in [0, None, ""]:
- current_page = 1
- if inputs_changed:
- gl.file_scan = False
- api_url = f"https://civitai.com/api/v1/models?limit={tile_count}&page=1"
- else:
- api_url = f"https://civitai.com/api/v1/models?limit={tile_count}&page={current_page}"
-
- if timeOut:
- if isNext:
- next_page = str(int(current_page) + 1)
- else:
- if current_page not in [1, 0, None, ""]:
- next_page = str(int(current_page) - 1)
- api_url = f"https://civitai.com/api/v1/models?limit={tile_count}&page={next_page}"
-
- if period_type:
- period_type = period_type.replace(" ", "")
- query = {'sort': sort_type, 'period': period_type}
-
- types_query_str = ""
-
- if content_type:
- types_query_str = "".join([f"&types={type}" for type in content_type])
-
- query_str = urllib.parse.urlencode(query, quote_via=urllib.parse.quote)
-
- if types_query_str:
- query_str += types_query_str
-
- if use_search_term != "None" and search_term:
- search_term = search_term.replace("\\","\\\\")
- if "civitai.com" in search_term:
- match = re.search(r'models/(\d+)', search_term)
- model_number = match.group(1)
- query_str = f"&ids={urllib.parse.quote(model_number)}"
- elif use_search_term == "User name":
- query_str += f"&username={urllib.parse.quote(search_term)}"
- elif use_search_term == "Tag":
- query_str += f"&tag={urllib.parse.quote(search_term)}"
- else:
- query_str += f"&query={urllib.parse.quote(search_term)}"
-
- if base_filter:
- for base in base_filter:
- query_str += f"&baseModels={urllib.parse.quote(base)}"
-
- if only_liked:
- query_str += f"&favorites=true"
-
- if nsfw == False:
- query_str += f"&nsfw=false"
-
- full_url = f"{api_url}&{query_str}"
-
- if gl.file_scan:
- highest_number = max(gl.url_list_with_numbers.keys())
- full_url = gl.url_list_with_numbers.get(int(current_page))
- nextPage = int(current_page) + 1
- prevPage = int(current_page) - 1
- data = request_civit_api(full_url)
- data["metadata"]["currentPage"] = current_page
- data["metadata"]["totalPages"] = highest_number
- if not nextPage > highest_number:
- data["metadata"]["nextPage"] = gl.url_list_with_numbers.get(nextPage)
- if not prevPage == 0:
- data["metadata"]["prevPage"] = gl.url_list_with_numbers.get(prevPage)
- else:
- data = request_civit_api(full_url)
-
- return data
-
def model_list_html(json_data):
video_playback = getattr(opts, "video_playback", True)
playback = ""
@@ -283,10 +210,10 @@ def model_list_html(json_data):
baseModel = "Not Found"
try:
- if 'updatedAt' in item['modelVersions'][0]:
- date = item['modelVersions'][0]['updatedAt'].split('T')[0]
+ if 'publishedAt' in item['modelVersions'][0]:
+ date = item['modelVersions'][0]['publishedAt'].split('T')[0]
except:
- baseModel = "Not Found"
+ date = "Not Found"
if gl.sortNewest:
if date not in sorted_models:
@@ -352,12 +279,45 @@ def model_list_html(json_data):
HTML += ''
return HTML
-def update_prev_page(content_type, sort_type, period_type, use_search_term, search_term, current_page, base_filter, only_liked, nsfw, tile_count):
- return update_next_page(content_type, sort_type, period_type, use_search_term, search_term, current_page, base_filter, only_liked, nsfw, tile_count, isNext=False)
-
-def update_next_page(content_type, sort_type, period_type, use_search_term, search_term, current_page, base_filter, only_liked, nsfw, tile_count, isNext=True):
- use_LORA = getattr(opts, "use_LORA", False)
+def create_api_url(content_type=None, sort_type=None, period_type=None, use_search_term=None, base_filter=None, only_liked=None, tile_count=None, search_term=None, nsfw=None, isNext=None):
+ base_url = "https://civitai.com/api/v1/models"
+ if isNext is not None:
+ return gl.json_data['metadata']['nextPage' if isNext else 'prevPage']
+
+ params = {'limit': tile_count, 'sort': sort_type, 'period': period_type.replace(" ", "") if period_type else None}
+
+ if content_type:
+ for ctype in content_type:
+ params["types"] = ctype
+
+ if use_search_term != "None" and search_term:
+ search_term = search_term.replace("\\", "\\\\")
+ if "civitai.com" in search_term:
+ model_number = re.search(r'models/(\d+)', search_term).group(1)
+ params = {'ids': model_number}
+ else:
+ key_map = {"User name": "username", "Tag": "tag"}
+ search_key = key_map.get(use_search_term, "query")
+ params[search_key] = search_term
+
+ if base_filter:
+ for base in base_filter:
+ params["baseModels"] = base
+
+ if only_liked:
+ params["favorites"] = "true"
+
+ if nsfw is False:
+ params["nsfw"] = "false"
+
+ query_string = urllib.parse.urlencode(params, doseq=True, quote_via=urllib.parse.quote)
+ full_url = f"{base_url}?{query_string}"
+
+ return full_url
+
+def convert_LORA_LoCon(content_type):
+ use_LORA = getattr(opts, "use_LORA", False)
if content_type:
if use_LORA and 'LORA & LoCon' in content_type:
content_type.remove('LORA & LoCon')
@@ -365,104 +325,110 @@ def update_next_page(content_type, sort_type, period_type, use_search_term, sear
content_type.append('LORA')
if 'LoCon' not in content_type:
content_type.append('LoCon')
-
- if not isinstance(gl.json_data, dict):
- timeOut = True
- return_values = update_model_list(content_type, sort_type, period_type, use_search_term, search_term, current_page, base_filter, only_liked, nsfw, timeOut=timeOut, isNext=isNext)
- timeOut = False
-
- return return_values
-
+ return content_type
+
+def initial_model_page(content_type=None, sort_type=None, period_type=None, use_search_term=None, search_term=None, current_page=None, base_filter=None, only_liked=None, nsfw=None, tile_count=None, from_update_tab=False):
+ content_type = convert_LORA_LoCon(content_type)
current_inputs = (content_type, sort_type, period_type, use_search_term, search_term, tile_count, base_filter, nsfw)
- if current_inputs != gl.previous_inputs and gl.previous_inputs != None:
- inputs_changed = True
- else:
- inputs_changed = False
-
- if inputs_changed:
- return_values = update_model_list(content_type, sort_type, period_type, use_search_term, search_term, current_page, base_filter, only_liked, nsfw, tile_count)
- return return_values
-
- if not gl.file_scan:
- if isNext:
- if gl.json_data['metadata']['nextPage'] is not None:
- gl.json_data = request_civit_api(gl.json_data['metadata']['nextPage'])
- else:
- gl.json_data = None
- else:
- if gl.json_data['metadata']['prevPage'] is not None:
- gl.json_data = request_civit_api(gl.json_data['metadata']['prevPage'])
- else:
- gl.json_data = None
- else:
- highest_number = max(gl.url_list_with_numbers.keys())
- if isNext:
- if gl.json_data['metadata']['nextPage'] is not None:
- currentPage = int(gl.json_data['metadata']['currentPage'])
- nextPage = currentPage + 2
- prevPage = currentPage
- pageCount = currentPage + 1
- gl.json_data = request_civit_api(gl.json_data['metadata']['nextPage'])
-
- gl.json_data["metadata"]["totalPages"] = highest_number
- if not nextPage > highest_number:
- gl.json_data["metadata"]["nextPage"] = gl.url_list_with_numbers.get(nextPage)
- if not prevPage == 0:
- gl.json_data["metadata"]["prevPage"] = gl.url_list_with_numbers.get(prevPage)
- gl.json_data["metadata"]["currentPage"] = pageCount
- else:
- gl.json_data = None
- else:
- if gl.json_data['metadata']['prevPage'] is not None:
- currentPage = int(gl.json_data['metadata']['currentPage'])
- nextPage = currentPage
- prevPage = currentPage - 2
- pageCount = currentPage - 1
- gl.json_data = request_civit_api(gl.json_data['metadata']['prevPage'])
-
- gl.json_data["metadata"]["totalPages"] = highest_number
- if not nextPage > highest_number:
- gl.json_data["metadata"]["nextPage"] = gl.url_list_with_numbers.get(nextPage)
- if not prevPage == 0:
- gl.json_data["metadata"]["prevPage"] = gl.url_list_with_numbers.get(prevPage)
- gl.json_data["metadata"]["currentPage"] = pageCount
- else:
- gl.json_data = None
-
- if gl.json_data is None:
- return
+ if current_inputs != gl.previous_inputs and gl.previous_inputs != None or not current_page:
+ current_page = 1
+ gl.previous_inputs = current_inputs
- if not isinstance(gl.json_data, dict):
- hasPrev = current_page not in [0, 1]
- hasNext = current_page == 1 or hasPrev
- model_dict = {}
+ if not from_update_tab:
+ gl.from_update_tab = False
- if gl.json_data == "timeout":
- HTML = api_error_msg("timeout")
- elif gl.json_data == "offline":
- HTML = api_error_msg("offline")
- elif gl.json_data == "error":
- HTML = api_error_msg("error")
+ if current_page == 1:
+ api_url = create_api_url(content_type, sort_type, period_type, use_search_term, base_filter, only_liked, tile_count, search_term, nsfw)
+ gl.url_list = {1 : api_url}
+ else:
+ api_url = gl.url_list.get(current_page)
+ else:
+ api_url = gl.url_list.get(current_page)
+ gl.from_update_tab = True
+
+ gl.json_data = request_civit_api(api_url)
+
+ max_page = 1
+ model_list = []
+ hasPrev, hasNext = False, False
+ if not isinstance(gl.json_data, dict):
+ HTML = api_error_msg(gl.json_data)
else:
- (hasPrev, hasNext, current_page, total_pages) = pagecontrol(gl.json_data)
- model_dict = {}
- try:
- gl.json_data['items']
- except TypeError:
- return gr.Dropdown.update(choices=[], value=None)
+ gl.json_data = insert_metadata(1)
+ metadata = gl.json_data['metadata']
+ hasNext = 'nextPage' in metadata
+ hasPrev = 'prevPage' in metadata
+
+ for item in gl.json_data['items']:
+ model_list.append(f"{item['name']} ({item['id']})")
+
+ max_page = max(gl.url_list.keys())
HTML = model_list_html(gl.json_data)
-
- page_string = f"Page: {current_page}/{total_pages}"
return (
- gr.Dropdown.update(choices=[v for k, v in model_dict.items()], value="", interactive=True), # Model List
+ gr.Dropdown.update(choices=model_list, value="", interactive=True), # Model List
gr.Dropdown.update(choices=[], value=""), # Version List
gr.HTML.update(value=HTML), # HTML Tiles
gr.Button.update(interactive=hasPrev), # Prev Page Button
gr.Button.update(interactive=hasNext), # Next Page Button
- gr.Slider.update(value=current_page, maximum=total_pages, label=page_string), # Page Count
+ gr.Slider.update(value=current_page, maximum=max_page), # Page Slider
+ gr.Button.update(interactive=False), # Save Tags
+ gr.Button.update(interactive=False), # Save Images
+ gr.Button.update(interactive=False, visible=False if gl.isDownloading else True), # Download Button
+ gr.Button.update(interactive=False, visible=False), # Delete Button
+ gr.Textbox.update(interactive=False, value=None, visible=True), # Install Path
+ gr.Dropdown.update(choices=[], value="", interactive=False), # Sub Folder List
+ gr.Dropdown.update(choices=[], value="", interactive=False), # File List
+ gr.HTML.update(value=''), # Preview HTML
+ gr.Textbox.update(value=None), # Trained Tags
+ gr.Textbox.update(value=None), # Base Model
+ gr.Textbox.update(value=None) # Model Filename
+ )
+
+def prev_model_page(content_type, sort_type, period_type, use_search_term, search_term, current_page, base_filter, only_liked, nsfw, tile_count):
+ return next_model_page(content_type, sort_type, period_type, use_search_term, search_term, current_page, base_filter, only_liked, nsfw, tile_count, isNext=False)
+
+def next_model_page(content_type, sort_type, period_type, use_search_term, search_term, current_page, base_filter, only_liked, nsfw, tile_count, isNext=True):
+ content_type = convert_LORA_LoCon(content_type)
+
+ current_inputs = (content_type, sort_type, period_type, use_search_term, search_term, tile_count, base_filter, nsfw)
+ if current_inputs != gl.previous_inputs and gl.previous_inputs != None:
+ return initial_model_page(content_type, sort_type, period_type, use_search_term, search_term, current_page, base_filter, only_liked, nsfw, tile_count)
+
+ api_url = create_api_url(isNext=isNext)
+ gl.json_data = request_civit_api(api_url)
+
+ next_page = current_page
+ model_list = []
+ max_page = 1
+ hasPrev, hasNext = False, False
+ if not isinstance(gl.json_data, dict):
+ HTML = api_error_msg(gl.json_data)
+
+ else:
+ next_page = current_page + 1 if isNext else current_page - 1
+
+ gl.json_data = insert_metadata(next_page, api_url)
+
+ metadata = gl.json_data['metadata']
+ hasNext = 'nextPage' in metadata
+ hasPrev = 'prevPage' in metadata
+
+ for item in gl.json_data['items']:
+ model_list.append(f"{item['name']} ({item['id']})")
+
+ max_page = max(gl.url_list.keys())
+ HTML = model_list_html(gl.json_data)
+
+ return (
+ gr.Dropdown.update(choices=model_list, value="", interactive=True), # Model List
+ gr.Dropdown.update(choices=[], value=""), # Version List
+ gr.HTML.update(value=HTML), # HTML Tiles
+ gr.Button.update(interactive=hasPrev), # Prev Page Button
+ gr.Button.update(interactive=hasNext), # Next Page Button
+ gr.Slider.update(value=next_page, maximum=max_page), # Current Page
gr.Button.update(interactive=False), # Save Tags
gr.Button.update(interactive=False), # Save Images
gr.Button.update(interactive=False, visible=False if gl.isDownloading else True), # Download Button
@@ -476,95 +442,20 @@ def update_next_page(content_type, sort_type, period_type, use_search_term, sear
gr.Textbox.update(value=None) # Model Filename
)
-def pagecontrol(json_data):
- current_page = f"{json_data['metadata']['currentPage']}"
- total_pages = f"{json_data['metadata']['totalPages']}"
- hasNext = False
- hasPrev = False
- if 'nextPage' in json_data['metadata']:
- hasNext = True
- if 'prevPage' in json_data['metadata']:
- hasPrev = True
- return hasPrev, hasNext, current_page, total_pages
-
-def update_model_list(content_type=None, sort_type=None, period_type=None, use_search_term=None, search_term=None, current_page=None, base_filter=None, only_liked=None, nsfw=None, tile_count=None, timeOut=None, isNext=None, from_ver=False, from_installed=False):
- use_LORA = getattr(opts, "use_LORA", False)
- model_list = []
+def insert_metadata(page_nr, api_url=None):
+ metadata = gl.json_data['metadata']
- if content_type:
- if use_LORA and 'LORA & LoCon' in content_type:
- content_type.remove('LORA & LoCon')
- if 'LORA' not in content_type:
- content_type.append('LORA')
- if 'LoCon' not in content_type:
- content_type.append('LoCon')
-
- if not from_ver and not from_installed:
- gl.ver_json = None
-
- current_inputs = (content_type, sort_type, period_type, use_search_term, search_term, tile_count, base_filter, nsfw)
- if current_inputs != gl.previous_inputs and gl.previous_inputs != None:
- inputs_changed = True
- else:
- inputs_changed = False
-
- gl.previous_inputs = current_inputs
-
- gl.json_data = api_to_data(content_type, sort_type, period_type, use_search_term, current_page, base_filter, only_liked, tile_count, search_term, nsfw, timeOut, isNext, inputs_changed)
- if gl.json_data is None:
- return
-
- if not isinstance(gl.json_data, dict):
- hasPrev = current_page not in [0, 1]
- hasNext = current_page == 1 or hasPrev
-
- if gl.json_data == "timeout":
- HTML = api_error_msg("timeout")
- elif gl.json_data == "offline":
- HTML = api_error_msg("offline")
- elif gl.json_data == "error":
- HTML = api_error_msg("error")
-
- if from_installed or from_ver:
- gl.json_data = gl.ver_json
+ if not metadata.get('prevPage', None) and page_nr > 1:
+ metadata['prevPage'] = gl.url_list.get((page_nr - 1))
- if isinstance(gl.json_data, dict):
- if not from_ver:
- (hasPrev, hasNext, current_page, total_pages) = pagecontrol(gl.json_data)
- else:
- current_page = 1
- total_pages = 1
- hasPrev = False
- hasNext = False
- for item in gl.json_data['items']:
- model_list.append(f"{item['name']} ({item['id']})")
-
- HTML = model_list_html(gl.json_data)
- else:
- current_page = 1
- total_pages = 1
+ if gl.from_update_tab:
+ if gl.url_list.get((page_nr + 1), None):
+ metadata['nextPage'] = gl.url_list.get((page_nr + 1))
- page_string = f"Page: {current_page}/{total_pages}"
+ elif page_nr not in gl.url_list:
+ gl.url_list[page_nr] = api_url
- return (
- gr.Dropdown.update(choices=model_list, value="", interactive=True), # Model List
- gr.Dropdown.update(choices=[], value=""), # Version List
- gr.HTML.update(value=HTML), # HTML Tiles
- gr.Button.update(interactive=hasPrev), # Prev Page Button
- gr.Button.update(interactive=hasNext), # Next Page Button
- gr.Slider.update(value=current_page, maximum=total_pages, label=page_string), # Page Count
- gr.Button.update(interactive=False), # Save Tags
- gr.Button.update(interactive=False), # Save Images
- gr.Button.update(interactive=False, visible=False if gl.isDownloading else True), # Download Button
- gr.Button.update(interactive=False, visible=False), # Delete Button
- gr.Textbox.update(interactive=False, value=None, visible=True), # Install Path
- gr.Dropdown.update(choices=[], value="", interactive=False), # Sub Folder List
- gr.Dropdown.update(choices=[], value="", interactive=False), # File List
- gr.HTML.update(value=''), # Preview HTML
- gr.Textbox.update(value=None), # Trained Tags
- gr.Textbox.update(value=None), # Base Model
- gr.Textbox.update(value=None) # Model Filename
- )
+ return gl.json_data
def update_model_versions(model_id, json_input=None):
if json_input:
@@ -702,8 +593,13 @@ def update_model_info(model_string=None, model_version=None, only_html=False, in
desc = item['description']
model_name = item['name']
model_folder = os.path.join(contenttype_folder(content_type, desc))
- model_uploader = item['creator']['username']
- uploader_avatar = item['creator']['image']
+ creator = item.get('creator', None)
+ if creator:
+ model_uploader = creator.get('username', '')
+ uploader_avatar = creator.get('image', '')
+ else:
+ model_uploader = 'User not found'
+ uploader_avatar = 'https://rawcdn.githack.com/gist/BlafKing/8d3f7a19e3f72cfddab46ae835037ee6/raw/296e81afbdd268200278beef478f3018b15936de/profile_placeholder.svg'
if uploader_avatar is None:
uploader_avatar = ''
else:
@@ -887,10 +783,15 @@ def update_model_info(model_string=None, model_version=None, only_html=False, in
f'{allow_svg if "Sell" in allowCommercialUse else deny_svg} Sell this model or merges using this model
'\
f'{allow_svg if item.get("allowDifferentLicense") else deny_svg} Have different permissions when sharing merges'\
''
+
+ if creator:
+ uploader = f''
+ else:
+ uploader = f'{escape(str(model_uploader))}{uploader_avatar}
'
output_html = f'''
-
+ {uploader}
- Version
@@ -1294,5 +1195,7 @@ def api_error_msg(input_string):
return div + "The CivitAI-API has timed out, please try again.
The servers might be too busy or down if the issue persists."
elif input_string == "offline":
return div + "The CivitAI servers are currently offline.
Please try again later."
- elif input_string == "error":
+ elif input_string == "no_items":
+ return div + "Failed to retrieve any models from CivitAI
The servers might be too busy or down if the issue persists."
+ else:
return div + "The CivitAI-API failed to respond due to an error.
Check the logs for more details."
\ No newline at end of file
diff --git a/scripts/civitai_file_manage.py b/scripts/civitai_file_manage.py
index 47f42fc..fb4c2aa 100644
--- a/scripts/civitai_file_manage.py
+++ b/scripts/civitai_file_manage.py
@@ -32,7 +32,6 @@ except ImportError:
gl.init()
-offlineHTML = 'The Civit-API has timed out, please try again.
The servers might be too busy or the selected model could not be found.
'
css_path = Path(__file__).resolve().parents[1] / "style_html.css"
no_update = False
from_ver = False
@@ -912,8 +911,10 @@ def file_scan(folders, ver_finish, tag_finish, installed_finish, preview_finish,
metadata = api_response_json.get('metadata', {})
url = metadata.get('nextPage', None)
elif response.status_code == 503:
+ print(f"Error: Received status code: {response.status_code} with URL: {url}")
+ print(response.text)
return (
- gr.HTML.update(value=offlineHTML),
+ gr.HTML.update(value=_api.api_error_msg("error")),
gr.Textbox.update(value=number)
)
else:
@@ -933,7 +934,7 @@ def file_scan(folders, ver_finish, tag_finish, installed_finish, preview_finish,
api_response['items'] = all_items
if api_response['items'] == []:
return (
- gr.HTML.update(value=offlineHTML),
+ gr.HTML.update(value=_api.api_error_msg("no_items")),
gr.Textbox.update(value=number)
)
@@ -965,43 +966,9 @@ def file_scan(folders, ver_finish, tag_finish, installed_finish, preview_finish,
model_chunks = list(chunks(all_model_ids, tile_count))
base_url = "https://civitai.com/api/v1/models?limit=100"
- gl.url_list_with_numbers = {i+1: f"{base_url}{''.join(chunk)}" for i, chunk in enumerate(model_chunks)}
-
- url_error = False
- api_url = gl.url_list_with_numbers.get(1)
+ gl.url_list = {i+1: f"{base_url}{''.join(chunk)}" for i, chunk in enumerate(model_chunks)}
- if not url_error:
- response = requests.get(api_url, timeout=(60,30), proxies=proxies, verify=ssl)
- try:
- if response.status_code == 200:
- response.encoding = "utf-8"
- gl.ver_json = json.loads(response.text)
-
- highest_number = max(gl.url_list_with_numbers.keys())
- gl.ver_json["metadata"]["totalPages"] = highest_number
-
- if highest_number > 1:
- gl.ver_json["metadata"]["nextPage"] = gl.url_list_with_numbers.get(2)
- else:
- print(f"Error: Received status code {response.status_code} for URL: {url}")
- url_error = True
- except requests.exceptions.Timeout:
- print(f"Request timed out for {url}. Skipping...")
- url_error = True
- except requests.exceptions.ConnectionError:
- print("Failed to connect to the API. The servers might be offline.")
- url_error = True
- except Exception as e:
- print(f"An unexpected error occurred: {e}")
- url_error = True
-
- if url_error:
- gl.scan_files = False
- return (
- gr.HTML.update(value=offlineHTML),
- gr.Textbox.update(value=number)
- )
- elif from_ver:
+ if from_ver:
gl.scan_files = False
return (
gr.HTML.update(value='Outdated models have been found.
Please press the button above to load the models into the browser tab
'),
@@ -1049,11 +1016,17 @@ def file_scan(folders, ver_finish, tag_finish, installed_finish, preview_finish,
gr.HTML.update(value=''),
gr.Textbox.update(value=number)
)
+
+def finish_returns():
+ return (
+ gr.Button.update(interactive=True, visible=True),
+ gr.Button.update(interactive=True, visible=True),
+ gr.Button.update(interactive=True, visible=True),
+ gr.Button.update(interactive=True, visible=True),
+ gr.Button.update(interactive=False, visible=False)
+ )
-def save_tag_start(tag_start):
- global from_tag, from_ver, from_installed, from_preview
- from_tag, from_ver, from_installed, from_preview = True, False, False, False
- number = _download.random_number(tag_start)
+def start_returns(number):
return (
gr.Textbox.update(value=number),
gr.Button.update(interactive=False, visible=False),
@@ -1063,70 +1036,40 @@ def save_tag_start(tag_start):
gr.Button.update(interactive=False, visible=True),
gr.HTML.update(value='')
)
+
+def save_tag_start(tag_start):
+ global from_tag, from_ver, from_installed, from_preview
+ from_tag, from_ver, from_installed, from_preview = True, False, False, False
+ number = _download.random_number(tag_start)
+ return start_returns(number)
def save_preview_start(preview_start):
global from_tag, from_ver, from_installed, from_preview
from_preview, from_tag, from_ver, from_installed = True, False, False, False
number = _download.random_number(preview_start)
- return (
- gr.Textbox.update(value=number),
- gr.Button.update(interactive=False, visible=False),
- gr.Button.update(interactive=True, visible=True),
- gr.Button.update(interactive=False, visible=True),
- gr.Button.update(interactive=False, visible=True),
- gr.Button.update(interactive=False, visible=True),
- gr.HTML.update(value='')
- )
+ return start_returns(number)
def installed_models_start(installed_start):
global from_installed, from_ver, from_tag, from_preview
from_installed, from_ver, from_tag, from_preview = True, False, False, False
number = _download.random_number(installed_start)
- return (
- gr.Textbox.update(value=number),
- gr.Button.update(interactive=False, visible=False),
- gr.Button.update(interactive=True, visible=True),
- gr.Button.update(interactive=False, visible=True),
- gr.Button.update(interactive=False, visible=True),
- gr.Button.update(interactive=False, visible=True),
- gr.HTML.update(value='')
- )
+ return start_returns(number)
def ver_search_start(ver_start):
global from_ver, from_tag, from_installed, from_preview
from_ver, from_tag, from_installed, from_preview = True, False, False, False
number = _download.random_number(ver_start)
- return (
- gr.Textbox.update(value=number),
- gr.Button.update(interactive=False, visible=False),
- gr.Button.update(interactive=True, visible=True),
- gr.Button.update(interactive=False, visible=True),
- gr.Button.update(interactive=False, visible=True),
- gr.Button.update(interactive=False, visible=True),
- gr.HTML.update(value='')
- )
+ return start_returns(number)
def save_tag_finish():
global from_tag
from_tag = False
- return (
- gr.Button.update(interactive=True, visible=True),
- gr.Button.update(interactive=True, visible=True),
- gr.Button.update(interactive=True, visible=True),
- gr.Button.update(interactive=True, visible=True),
- gr.Button.update(interactive=False, visible=False)
- )
+ return finish_returns()
def save_preview_finish():
global from_preview
from_preview = False
- return (
- gr.Button.update(interactive=True, visible=True),
- gr.Button.update(interactive=True, visible=True),
- gr.Button.update(interactive=True, visible=True),
- gr.Button.update(interactive=True, visible=True),
- gr.Button.update(interactive=False, visible=False)
- )
+ return finish_returns()
def scan_finish():
return (
@@ -1140,24 +1083,8 @@ def scan_finish():
def load_to_browser(content_type, sort_type, period_type, use_search_term, search_term, tile_count, base_filter, nsfw):
global from_ver, from_installed
- if from_ver:
- model_list_return = _api.update_model_list(from_ver=True, tile_count=tile_count)
- if from_installed:
- model_list_return = _api.update_model_list(from_installed=True, tile_count=tile_count)
- use_LORA = getattr(opts, "use_LORA", False)
- if content_type:
- if use_LORA and 'LORA & LoCon' in content_type:
- content_type.remove('LORA & LoCon')
- if 'LORA' not in content_type:
- content_type.append('LORA')
- if 'LoCon' not in content_type:
- content_type.append('LoCon')
-
- current_inputs = (content_type, sort_type, period_type, use_search_term, search_term, tile_count, base_filter, nsfw)
- gl.previous_inputs = current_inputs
-
- gl.file_scan = True
+ model_list_return = _api.initial_model_page(content_type, sort_type, period_type, use_search_term, search_term, 1, base_filter, False, nsfw, tile_count, True)
from_ver, from_installed = False, False
return (
*model_list_return,
diff --git a/scripts/civitai_global.py b/scripts/civitai_global.py
index 71567dd..fc57dc9 100644
--- a/scripts/civitai_global.py
+++ b/scripts/civitai_global.py
@@ -3,7 +3,7 @@ def init():
from urllib3.exceptions import InsecureRequestWarning
warnings.simplefilter('ignore', InsecureRequestWarning)
- global download_queue, last_version, cancel_status, recent_model, json_data, json_info, main_folder, previous_inputs, download_fail, sortNewest, isDownloading, old_download, scan_files, ver_json, file_scan, url_list_with_numbers, print
+ global download_queue, last_version, cancel_status, recent_model, last_url, json_data, json_info, main_folder, previous_inputs, download_fail, sortNewest, isDownloading, old_download, scan_files, from_update_tab, url_list, print
cancel_status = None
recent_model = None
@@ -12,11 +12,10 @@ def init():
main_folder = None
previous_inputs = None
last_version = None
- ver_json = None
- url_list_with_numbers = None
+ url_list = {}
download_queue = []
- file_scan = False
+ from_update_tab = False
scan_files = False
download_fail = False
sortNewest = False
diff --git a/scripts/civitai_gui.py b/scripts/civitai_gui.py
index 3237ef4..4ac3015 100644
--- a/scripts/civitai_gui.py
+++ b/scripts/civitai_gui.py
@@ -206,7 +206,7 @@ def on_ui_tabs():
with gr.Row(elem_id=header):
with gr.Row(elem_id="pageBox"):
get_prev_page = gr.Button(value="Prev page", interactive=False, elem_id="pageBtn1")
- page_slider = gr.Slider(label='Current page', step=1, minimum=1, maximum=1, value=1, min_width=80, elem_id="pageSlider")
+ page_slider = gr.Slider(label='Current page:', step=1, minimum=1, maximum=1, min_width=80, elem_id="pageSlider")
get_next_page = gr.Button(value="Next page", interactive=False, elem_id="pageBtn2")
with gr.Row(elem_id="pageBoxMobile"):
pass # Row used for button placement on mobile
@@ -301,6 +301,7 @@ def on_ui_tabs():
dl_url = gr.Textbox(visible=False)
civitai_text2img_output = gr.Textbox(visible=False)
civitai_text2img_input = gr.Textbox(elem_id="civitai_text2img_input", visible=False)
+ page_slider_trigger = gr.Textbox(elem_id="page_slider_trigger", visible=False)
selected_model_list = gr.Textbox(elem_id="selected_model_list", visible=False)
selected_type_list = gr.Textbox(elem_id="selected_type_list", visible=False)
html_cancel_input = gr.Textbox(elem_id="html_cancel_input", visible=False)
@@ -310,6 +311,7 @@ def on_ui_tabs():
model_select = gr.Textbox(elem_id="model_select", visible=False)
model_sent = gr.Textbox(elem_id="model_sent", visible=False)
type_sent = gr.Textbox(elem_id="type_sent", visible=False)
+ empty = gr.Textbox(value="", visible=False)
download_start = gr.Textbox(visible=False)
download_finish = gr.Textbox(visible=False)
tag_start = gr.Textbox(visible=False)
@@ -684,6 +686,8 @@ def on_ui_tabs():
tile_count_slider
]
+ refresh_inputs = [empty if item == page_slider else item for item in page_inputs]
+
page_outputs = [
list_models,
list_versions,
@@ -740,19 +744,21 @@ def on_ui_tabs():
# Page Button Functions #
page_btn_list = {
- refresh.click: _api.update_model_list,
- search_term.submit: _api.update_model_list,
- get_next_page.click: _api.update_next_page,
- get_prev_page.click: _api.update_prev_page
+ refresh.click: (_api.initial_model_page, True),
+ search_term.submit: (_api.initial_model_page, True),
+ page_slider_trigger.change: (_api.initial_model_page, False),
+ get_next_page.click: (_api.next_model_page, False),
+ get_prev_page.click: (_api.prev_model_page, False)
}
- for trigger, function in page_btn_list.items():
- trigger(fn=function, inputs=page_inputs, outputs=page_outputs)
+ for trigger, (function, use_refresh_inputs) in page_btn_list.items():
+ inputs_to_use = refresh_inputs if use_refresh_inputs else page_inputs
+ trigger(fn=function, inputs=inputs_to_use, outputs=page_outputs)
trigger(fn=None, _js="() => multi_model_select()")
for button in cancel_btn_list:
button.click(fn=_file.cancel_scan)
-
+
# Update model Functions #
ver_search.click(