Upload 3 files
Browse files- javascript/colab_sd_models.js +244 -0
- scripts/colab_sd_models.py +242 -0
- style.css +302 -0
javascript/colab_sd_models.js
ADDED
@@ -0,0 +1,244 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
document.addEventListener('DOMContentLoaded', () => {
|
2 |
+
const observer = new MutationObserver((mutations) => {
|
3 |
+
mutations.forEach((mutation) => {
|
4 |
+
if (mutation.addedNodes) {
|
5 |
+
mutation.addedNodes.forEach((node) => {
|
6 |
+
if (node.id === 'tab_models_list') {
|
7 |
+
// запуск кода после загрузки элементов
|
8 |
+
Array.from(document.querySelectorAll('#tabs > div.tab-nav > button')).find(button => button.textContent.includes('модели')).click();
|
9 |
+
// переопределение параметров колонок на основе числа моделей в категории
|
10 |
+
const models_checkbox_grids = document.querySelectorAll("#tab_models_list fieldset > div[data-testid='checkbox-group']");
|
11 |
+
models_checkbox_grids.forEach(models_checkbox_grid => {
|
12 |
+
const model_label = models_checkbox_grid.querySelectorAll('label');
|
13 |
+
const numColumns = model_label.length > 9 ? 'repeat(auto-fit, minmax(250px, 1fr))' : '1fr';
|
14 |
+
models_checkbox_grid.style.gridTemplateColumns = numColumns;
|
15 |
+
});
|
16 |
+
// подвсетка категории мужицких моделей (костаыль, потому что градио своим скриптом долбит каждые Nms переопределение классов)
|
17 |
+
const intervalId = setInterval(() => {
|
18 |
+
const modelsNavButtons = document.querySelectorAll("div#tab_models_list > div.gap > div.tabs > div.tab-nav > button");
|
19 |
+
const MaleCat = Array.from(modelsNavButtons).find(button => button.textContent.includes('мужские'));
|
20 |
+
if (MaleCat) {
|
21 |
+
MaleCat.setAttribute("id", "male_only");
|
22 |
+
}
|
23 |
+
}, 100);
|
24 |
+
// получение инфы по кд о свободном пространтсве из скрытого уродского текстбокса в красивый элементик в шапочке
|
25 |
+
const freespacetextarea = document.querySelector("#free_space_area > label > textarea");
|
26 |
+
const frespace_out = document.querySelector("#frespace_out");
|
27 |
+
let prevValue = freespacetextarea.value;
|
28 |
+
setInterval(function () {
|
29 |
+
const currentValue = freespacetextarea.value;
|
30 |
+
if (currentValue !== prevValue) {
|
31 |
+
frespace_out.innerHTML = `${currentValue}`;
|
32 |
+
prevValue = currentValue;
|
33 |
+
}
|
34 |
+
}, 100);
|
35 |
+
// скликивание реальной но скрытой уродской кнопки с обработчиком проверки свободного места при нажатии на фейковую но красивую кнопочку
|
36 |
+
const freespace_getButton = document.querySelector("#freespace_get");
|
37 |
+
const free_spaceOrigButton = document.querySelector("#free_space_button");
|
38 |
+
freespace_getButton.addEventListener("click", function () {
|
39 |
+
free_spaceOrigButton.click();
|
40 |
+
});
|
41 |
+
// копирование реальных элементов из вкладок с моделями в результатах поиска
|
42 |
+
const SearchBlock = document.querySelector('#clear_search_models_results').closest('label').closest('div').closest('div').closest('div');
|
43 |
+
const ModelDLHeaderBlock = document.querySelector('.models_dl_header').closest('div').parentNode.closest('div').closest('div');
|
44 |
+
const ModelDLHeaderContainer = document.querySelector('.models_dl_header').closest('div').parentNode;
|
45 |
+
ModelDLHeaderBlock.appendChild(SearchBlock);
|
46 |
+
// небольшой css-фикс
|
47 |
+
ModelDLHeaderContainer.style.cssText = `display: flex; flex-direction: row; align-items: center; justify-content: flex-start; flex-wrap: wrap;`;
|
48 |
+
document.querySelector('.models_dl_header').parentNode.style.marginRight = "50px";
|
49 |
+
// фильтрация моделей при вводе
|
50 |
+
const searchInput = document.querySelector('input[type="text"]');
|
51 |
+
const findedModels = document.querySelector('#finded_models');
|
52 |
+
const tabModelsList = document.querySelector('#tab_models_list');
|
53 |
+
const labels = tabModelsList.querySelectorAll('label');
|
54 |
+
const clearSearchResultsButton = document.querySelector("#clear_search_models_results");
|
55 |
+
searchInput.addEventListener('input', (event) => {
|
56 |
+
const searchTerm = event.target.value.toLowerCase();
|
57 |
+
findedModels.innerHTML = '';
|
58 |
+
if (searchTerm !== '') {
|
59 |
+
labels.forEach((label) => {
|
60 |
+
const labelText = label.textContent.toLowerCase();
|
61 |
+
if (labelText.includes(searchTerm)) {
|
62 |
+
const clone = label.cloneNode(true);
|
63 |
+
findedModels.appendChild(clone);
|
64 |
+
const originalCheckbox = label.querySelector('input[type="checkbox"]');
|
65 |
+
const clonedCheckbox = clone.querySelector('input[type="checkbox"]');
|
66 |
+
clonedCheckbox.addEventListener('change', () => {
|
67 |
+
originalCheckbox.click();
|
68 |
+
});
|
69 |
+
}
|
70 |
+
});
|
71 |
+
}
|
72 |
+
});
|
73 |
+
// обработчик на кнопочку очистки результатов
|
74 |
+
clearSearchResultsButton.addEventListener('click', () => {
|
75 |
+
findedModels.innerHTML = '';
|
76 |
+
searchInput.value = '';
|
77 |
+
});
|
78 |
+
// автоматическое скликивание скрытых кнопок для подгрузки установленных моделей и свободного места после загрузки дополнения через 1 сек
|
79 |
+
setTimeout(() => document.querySelector("#files_button").click(), 1000);
|
80 |
+
setTimeout(() => document.querySelector("#free_space_button").click(), 1000);
|
81 |
+
// файловый менеджер на тексбоксах
|
82 |
+
setTimeout(() => {
|
83 |
+
const filesArea = document.querySelector("#files_area > label > textarea");
|
84 |
+
const filesCheckbox = document.querySelector("#files_checkbox");
|
85 |
+
const deleteArea = document.querySelector("#delete_area > label > textarea");
|
86 |
+
// обновление списка чекбоксов с файлами при изменении списка путей в текстбоксе
|
87 |
+
function addCheckboxEventListeners() {
|
88 |
+
const delete_checkboxes = document.querySelectorAll("#files_checkbox > label > input[type=checkbox]");
|
89 |
+
delete_checkboxes.forEach(checkbox => {
|
90 |
+
checkbox.addEventListener("change", event => {
|
91 |
+
// отмеченные на удаление делаем красными и зачеркнутыми
|
92 |
+
const delete_span = event.target.parentElement.querySelector("span");
|
93 |
+
if (event.target.checked) {
|
94 |
+
delete_span.style.textDecoration = "line-through";
|
95 |
+
delete_span.style.color = "#ed5252";
|
96 |
+
} else {
|
97 |
+
delete_span.style.textDecoration = "none";
|
98 |
+
delete_span.style.color = "";
|
99 |
+
}
|
100 |
+
});
|
101 |
+
});
|
102 |
+
}
|
103 |
+
// функция для обновления чекбоксов с файлами почти в реальном времени
|
104 |
+
function updateCheckboxes() {
|
105 |
+
while (filesCheckbox.firstChild) {
|
106 |
+
filesCheckbox.removeChild(filesCheckbox.firstChild);
|
107 |
+
}
|
108 |
+
const fileNames = filesArea.value.split("\n").map(path => path.split("/").pop());
|
109 |
+
if (fileNames.length === 0 || (fileNames.length === 1 && fileNames[0] === "")) {
|
110 |
+
const message = document.createElement("p");
|
111 |
+
message.textContent = "ничего не найдено";
|
112 |
+
filesCheckbox.appendChild(message);
|
113 |
+
} else {
|
114 |
+
fileNames.forEach(fileName => {
|
115 |
+
const checkbox = document.createElement("input");
|
116 |
+
checkbox.type = "checkbox";
|
117 |
+
checkbox.id = fileName;
|
118 |
+
checkbox.addEventListener("change", event => {
|
119 |
+
if (event.target.checked) {
|
120 |
+
deleteArea.value += (deleteArea.value ? "\n" : "") + fileName;
|
121 |
+
} else {
|
122 |
+
const lines = deleteArea.value.split("\n");
|
123 |
+
const index = lines.indexOf(fileName);
|
124 |
+
if (index !== -1) {
|
125 |
+
lines.splice(index, 1);
|
126 |
+
deleteArea.value = lines.join("\n");
|
127 |
+
}
|
128 |
+
}
|
129 |
+
deleteArea.dispatchEvent(new Event('input')); // имитация ввода, это самая важная часть кода
|
130 |
+
});
|
131 |
+
const label = document.createElement("label");
|
132 |
+
label.htmlFor = fileName;
|
133 |
+
label.className = "filecheckbox";
|
134 |
+
const span = document.createElement("span");
|
135 |
+
span.textContent = fileName;
|
136 |
+
label.appendChild(checkbox);
|
137 |
+
label.appendChild(span);
|
138 |
+
filesCheckbox.appendChild(label);
|
139 |
+
});
|
140 |
+
}
|
141 |
+
deleteArea.value = deleteArea.value.trim();
|
142 |
+
deleteArea.dispatchEvent(new Event('input')); // имитация ввода, без этого не работает
|
143 |
+
addCheckboxEventListeners()
|
144 |
+
}
|
145 |
+
// наблюдаем за скрытым тексбоксом с путями до моделей и обнов��ям чекбоксы
|
146 |
+
const observer = new MutationObserver(updateCheckboxes);
|
147 |
+
observer.observe(filesArea, { characterData: true, subtree: true });
|
148 |
+
updateCheckboxes();
|
149 |
+
// скликивание реальной но скрытой уродской кнопки с обработчиком обновления списка файлов при нажатии на фейковую но красивую кнопочку
|
150 |
+
const RefreshFilesButton = document.querySelector("#refresh_files_button");
|
151 |
+
RefreshFilesButton.addEventListener("click", () => {
|
152 |
+
document.querySelector("#files_button").click();
|
153 |
+
// задержки по 3 секунды необходимы, чтобы колаб одуплился
|
154 |
+
setTimeout(function () { updateCheckboxes(); }, 3000);
|
155 |
+
});
|
156 |
+
// при клике на фейковую кнопочку удаления - произойдет и обновление списка файлов с задержкой 3 сек
|
157 |
+
document.querySelector("#delete_button").addEventListener("click", function () {
|
158 |
+
setTimeout(function () {
|
159 |
+
document.querySelector("#files_button").click();
|
160 |
+
// задержки по 3 секунды необходимы, чтобы колаб одуплился
|
161 |
+
setTimeout(function () { updateCheckboxes(); }, 3000);
|
162 |
+
}, 3000);
|
163 |
+
});
|
164 |
+
// скликивание реальной но скрытой уродской кнопки с обработчиком удаления моделей при нажатии на фейковую но красивую кнопочку
|
165 |
+
const OrigDelButton = document.querySelector("#delete_button");
|
166 |
+
const CustomDelButton = document.querySelector("#delete_files_button");
|
167 |
+
CustomDelButton.addEventListener("click", () => {
|
168 |
+
OrigDelButton.click();
|
169 |
+
});
|
170 |
+
// проверка выхлопа из функции загрузки в скрытом текстбоксе
|
171 |
+
setInterval(function () {
|
172 |
+
var DLresultText = document.querySelector("#downloads_result_text > span.finish_dl_func");
|
173 |
+
DLresultText.textContent = document.querySelector("#dlresultbox > label > textarea").value;
|
174 |
+
// функция скрытия прогрессбара
|
175 |
+
function checkDLresult(element, text) {
|
176 |
+
if (element.textContent.includes(text)) {
|
177 |
+
document.querySelector("div.downloads_result_container > div.models_porgress_loader").style.removeProperty("display");
|
178 |
+
document.querySelector("#downloads_start_text").style.removeProperty("display");
|
179 |
+
document.querySelector("#downloads_result_text > span.dl_progress_info").textContent = "чтобы новые файлы появились в выпадающем списке моделей, нужно обновить их список по соответсвующей кнопке";
|
180 |
+
}
|
181 |
+
}
|
182 |
+
// просто скрываем прогрессбар если в выхлопе есть фраза о завершении или предупреждение
|
183 |
+
checkDLresult(DLresultText, "заверш");
|
184 |
+
checkDLresult(DLresultText, "слишком");
|
185 |
+
checkDLresult(DLresultText, "ОШИБКА");
|
186 |
+
// раскрашиваем текст сообщения о результате выполнения, если что-то пошло не так
|
187 |
+
if (DLresultText) {
|
188 |
+
if (DLresultText.textContent.includes("слишком")) {
|
189 |
+
DLresultText.style.setProperty("color", "#ff4f8b", "important");
|
190 |
+
} else if (DLresultText.textContent.includes("ОШИБКА")) {
|
191 |
+
DLresultText.style.setProperty("color", "#de2f2f", "important");
|
192 |
+
} else if (DLresultText.textContent.includes("заверш")) {
|
193 |
+
DLresultText.style.setProperty("color", "#99fb99", "important");
|
194 |
+
}
|
195 |
+
}
|
196 |
+
}, 200);
|
197 |
+
// действия по клику на фейковую но видимую кнопку для скачивания
|
198 |
+
document.querySelector("#general_download_button").addEventListener("click", function () {
|
199 |
+
// очистка текстбокса от выхлопа предыдущего выполнения
|
200 |
+
var resultTextareaDL = document.querySelector("#dlresultbox > label > textarea");
|
201 |
+
resultTextareaDL.value = "";
|
202 |
+
var resultClearOut = new Event("input", { bubbles: true }); // без этого не будет работать обноволение .value
|
203 |
+
resultTextareaDL.dispatchEvent(resultClearOut);
|
204 |
+
// делаем прогрессбар и место для результирующего текста видимыми
|
205 |
+
const DLprogressBar = document.querySelector("div.downloads_result_container > div.models_porgress_loader");
|
206 |
+
DLprogressBar.style.setProperty("display", "block", "important");
|
207 |
+
const DLresultText = document.querySelector("#downloads_result_text");
|
208 |
+
DLresultText.style.setProperty("display", "block", "important");
|
209 |
+
document.querySelector("#downloads_start_text").style.setProperty("display", "block", "important");
|
210 |
+
// скликивание реальных но скрытых кнопок с обработчиками загрузки файлов по чекбоксам и кастомных ссылок при нажатии на фейковую но кнопочку
|
211 |
+
// формирование списка из кастомных ссылок
|
212 |
+
document.querySelector("#ownlinks_download_button").click();
|
213 |
+
setTimeout(function () {
|
214 |
+
// через 3 сек. добавим его к списку ссылок из чекбоксов и отправим на загрузку вместе
|
215 |
+
document.querySelector("#checkboxes_download_button").click();
|
216 |
+
}, 3000); // задержка, чтобы колаб успел одуплиться
|
217 |
+
});
|
218 |
+
// если кнопка загрузки уже нажата, запрещаем кликать еще раз пока функция загрузки не выплюнет ответ
|
219 |
+
var GendownloadButton = document.querySelector("#general_download_button");
|
220 |
+
var DLprogressBar = document.querySelector("div.downloads_result_container > div.models_porgress_loader");
|
221 |
+
if (GendownloadButton && DLprogressBar) {
|
222 |
+
var DLobserver = new MutationObserver(function (mutations) {
|
223 |
+
mutations.forEach(function (mutation) {
|
224 |
+
if (mutation.type === "attributes" && mutation.attributeName === "style") { // отслеживание видимости прогрессбара
|
225 |
+
if (DLprogressBar.style.display === "block") {
|
226 |
+
GendownloadButton.setAttribute("disabled", "disabled");
|
227 |
+
} else {
|
228 |
+
setTimeout(function () {
|
229 |
+
GendownloadButton.removeAttribute("disabled");
|
230 |
+
}, 3000); // не сразу даем кликнуть снова, а после ожидания 3 секунды, чтобы не закликали
|
231 |
+
}
|
232 |
+
}
|
233 |
+
});
|
234 |
+
});
|
235 |
+
DLobserver.observe(DLprogressBar, { attributes: true });
|
236 |
+
}
|
237 |
+
}, 9000); // запуск скриптов через 9 секунд после загрузки вебуи, чтобы успели отработать скрипты других дополнений и градио
|
238 |
+
}
|
239 |
+
});
|
240 |
+
}
|
241 |
+
});
|
242 |
+
});
|
243 |
+
observer.observe(document.body, { childList: true, subtree: true });
|
244 |
+
});
|
scripts/colab_sd_models.py
ADDED
@@ -0,0 +1,242 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import re
|
3 |
+
import requests
|
4 |
+
import shutil
|
5 |
+
import subprocess
|
6 |
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
7 |
+
|
8 |
+
import gradio as gr
|
9 |
+
from bs4 import BeautifulSoup
|
10 |
+
from modules import script_callbacks, scripts, shared, sd_models
|
11 |
+
from modules.paths_internal import data_path
|
12 |
+
|
13 |
+
|
14 |
+
urlprefix = "https://huggingface.co/2ch/models/resolve/main/"
|
15 |
+
models_json_data = requests.get(urlprefix + "colab_models.json").json()
|
16 |
+
wget = "wget -nv -t 10 --show-progress --progress=bar:force -q --content-disposition "
|
17 |
+
sdroot = data_path
|
18 |
+
models_folder_path = sd_models.model_path
|
19 |
+
loras_folder_path = shared.cmd_opts.lora_dir
|
20 |
+
embeddings_folder_path = shared.cmd_opts.embeddings_dir
|
21 |
+
ct = "token=542c1d6077168822e1b49e30e3437a5d"
|
22 |
+
|
23 |
+
|
24 |
+
def on_ui_tabs():
|
25 |
+
with gr.Blocks() as models_list:
|
26 |
+
# шапка вкладки с поиском и свободным местом на диске
|
27 |
+
gr.HTML(
|
28 |
+
"""<div class="models_top_container"><div class="models_top_header_text"><h1 class="models_dl_header">выбор и скачивание моделей</h1><p>учитывай весьма ограниченное пространство на диске в колабе!</p></div><div class="freespaceinfo"><div id="frespace_output"><span>свободно в колабе: <span id="frespace_out">нажми на кнопочку</span></div><div id="freespace_get"></div></div></div>""")
|
29 |
+
search_and_results = gr.HTML(
|
30 |
+
"""<label id="models_search_field"><input type="text" id="models_search_input" class="svelte-1pie7s6" placeholder="начни вводить для поиска"/><span id="clear_search_models_results"></span></label><div id="finded_models"></div>""")
|
31 |
+
# вкладки с категориями
|
32 |
+
buttons = []
|
33 |
+
checkbox_groups = []
|
34 |
+
checkboxes = []
|
35 |
+
for category in models_json_data['categories']:
|
36 |
+
categories = ["models_A", "models_B", "models_C", "models_D", "models_E", "models_F", "models_G", "models_H", "models_I", "models_J", "models_K", "models_L", "models_M", "models_N", "models_O", "models_P", "models_Q"]
|
37 |
+
tab_names = ["аниме", "лайнарт", "женские", "игры и кино", "техника и космос", "крипота", "макро", "мемные", "мужские", "мультфильмы", "пиксельарт", "трехмерная графика", "универсальные", "фотореализм", "фурри", "футанари",
|
38 |
+
"художественные"]
|
39 |
+
category_map = dict(zip(categories, tab_names))
|
40 |
+
tab_name = category_map.get(category)
|
41 |
+
with gr.Tab(tab_name):
|
42 |
+
checkbox_group = gr.CheckboxGroup(sorted(models_json_data['categories'][category], key=lambda x: x.lower()), label="")
|
43 |
+
checkboxes.append(checkbox_group)
|
44 |
+
checkbox_groups.append(checkbox_group)
|
45 |
+
# ссылки для реквеста добавления моделей
|
46 |
+
gr.HTML(
|
47 |
+
"""<div class="request_new_models">не нашел нужную модель? запрос на добавление можно отправить в <a href="https://t.me/colabSDbot" target="_blank">бота</a> или <a href="https://t.me/stabdiff" target="_blank">группу</a>.</div>""")
|
48 |
+
|
49 |
+
# функция для формирования списка своих ссылок
|
50 |
+
def get_own_links(ownmodels, ownloras, ownembeddings):
|
51 |
+
urls = []
|
52 |
+
for text, dlpath in zip([ownmodels, ownloras, ownembeddings], [models_folder_path, loras_folder_path, embeddings_folder_path]):
|
53 |
+
lines = text.split("\n")
|
54 |
+
for line in lines:
|
55 |
+
if line.strip():
|
56 |
+
# url = wget+line+" -P "+dlpath
|
57 |
+
link = line.strip() + (f'?{ct}' if '?' not in line else f'&{ct}') if 'civitai' in line else line.strip()
|
58 |
+
url = f'{wget}"{link}" -P {dlpath}'
|
59 |
+
urls.append(url)
|
60 |
+
own_urls = os.path.join(sdroot, "urls.txt")
|
61 |
+
with open(own_urls, "w") as f:
|
62 |
+
for url in urls:
|
63 |
+
f.write(url + "\n")
|
64 |
+
print("список загрузки сформирован...")
|
65 |
+
|
66 |
+
# текстбоксы для указания своих ссылок
|
67 |
+
gr.HTML("""<div class="ownfiles_header"><h2>здесь можно указать прямые ссылки на загрузку моделей, лор и внедрений</h2></div>""")
|
68 |
+
with gr.Row():
|
69 |
+
plhd = """вставляй каждую ссылку с новой строки!\nпримеры ссылок:\nhttps://models.tensorplay.ai/104249\nhttps://civitai.com/api/download/models/110660\nhttps://huggingface.co/2ch/gay/resolve/main/lora/BettercocksFlaccid.safetensors"""
|
70 |
+
ownmodels = gr.Textbox(label="модели", placeholder=plhd, info="прямые ссылки на Checkpoints", lines=5, elem_id="ownmodels")
|
71 |
+
ownloras = gr.Textbox(label="лоры", placeholder=plhd, info="прямые ссылки на LoRas", lines=5, elem_id="ownloras")
|
72 |
+
ownembeddings = gr.Textbox(label="внедрения", placeholder=plhd, info="прямые ссылки на Textual Inversions", lines=5, elem_id="ownembeddings")
|
73 |
+
# кнопка при нажатии на которую происходит сначала клик на кнопку формирования списка своих ссылок, а потом на кнопку основной функции загрузки
|
74 |
+
download_button = gr.Button("скачать выбранные модели", elem_id="general_download_button")
|
75 |
+
# кнопка для формирования списка своих ссылок
|
76 |
+
button = gr.Button("скачать по ссылкам", elem_id="ownlinks_download_button")
|
77 |
+
button.click(get_own_links, inputs=[ownmodels, ownloras, ownembeddings])
|
78 |
+
# кнопка для отправки на загрузку
|
79 |
+
download_button = gr.Button("скачать отмеченные модели", elem_id="checkboxes_download_button")
|
80 |
+
|
81 |
+
# функция определения точки монтирования и свободного места на диске
|
82 |
+
def find_mount_point():
|
83 |
+
# __file__ = "."
|
84 |
+
path = os.path.realpath(__file__)
|
85 |
+
path = os.path.abspath(path)
|
86 |
+
while not os.path.ismount(path):
|
87 |
+
path = os.path.dirname(path)
|
88 |
+
return path
|
89 |
+
|
90 |
+
def free_space():
|
91 |
+
total, used, free = shutil.disk_usage(find_mount_point())
|
92 |
+
power = 2 ** 10
|
93 |
+
n = 0
|
94 |
+
power_labels = {0: '', 1: 'Кило', 2: 'Мега', 3: 'Гига', 4: 'Тера'}
|
95 |
+
while free > power:
|
96 |
+
free /= power
|
97 |
+
n += 1
|
98 |
+
return f"{free:.2f} {power_labels[n]}байт"
|
99 |
+
|
100 |
+
# функция вычисления общего размера загружаемых файлов в байтах
|
101 |
+
def get_file_size(url):
|
102 |
+
url = re.search(r'https?://\S+', url).group()
|
103 |
+
|
104 |
+
def contleght(url):
|
105 |
+
return int(requests.get(url, stream=True).headers.get('Content-Length', 0))
|
106 |
+
|
107 |
+
if "huggingface" in url:
|
108 |
+
try:
|
109 |
+
try:
|
110 |
+
file_size = int(next((pre.text.split('size ')[1].split('\n')[0] for pre in BeautifulSoup(requests.get(url.replace('resolve', 'blame')).text, 'html.parser').find_all('pre') if 'size' in pre.text)))
|
111 |
+
except:
|
112 |
+
file_size_text = BeautifulSoup(requests.get(url.replace('resolve', 'blob')).text, 'html.parser').find('strong', string='Size of remote file:').next_sibling.strip()
|
113 |
+
file_size = int(float(file_size_text.split()[0]) * {'KB': 1024, 'MB': 1024 ** 2, 'GB': 1024 ** 3, 'TB': 1024 ** 4}[file_size_text.split()[1]])
|
114 |
+
except:
|
115 |
+
file_size = contleght(url)
|
116 |
+
if file_size < 1048576: file_size = contleght(url)
|
117 |
+
elif "civitai" in url:
|
118 |
+
try:
|
119 |
+
file_size = int(requests.get("https://civitai.com/api/v1/model-versions/" + url.split('/')[-1] + civitai_token).json()["files"][0]["sizeKB"] * 1024)
|
120 |
+
except:
|
121 |
+
file_size = contleght(url)
|
122 |
+
if file_size < 1048576: file_size = contleght(url)
|
123 |
+
else:
|
124 |
+
file_size = contleght(url)
|
125 |
+
return file_size
|
126 |
+
|
127 |
+
# основная функция для загрузки отмеченных чекбоксов
|
128 |
+
def start_download(*checkbox_groups):
|
129 |
+
try:
|
130 |
+
urls = []
|
131 |
+
for checkbox_group in checkbox_groups:
|
132 |
+
selected_choices = checkbox_group
|
133 |
+
for choice in selected_choices:
|
134 |
+
if choice in models_json_data["models"]:
|
135 |
+
file_names = models_json_data["models"][choice].split(',')
|
136 |
+
for file_name in file_names:
|
137 |
+
url = wget + urlprefix + file_name.strip() + " -P " + models_folder_path
|
138 |
+
urls.append(url)
|
139 |
+
own_urls = os.path.join(sdroot, "urls.txt")
|
140 |
+
with open(own_urls, "r") as f:
|
141 |
+
own_links = f.read().splitlines()
|
142 |
+
urls.extend(own_links)
|
143 |
+
os.remove(own_urls)
|
144 |
+
except Exception as e:
|
145 |
+
print(f"ОШИБКА: {e}")
|
146 |
+
return f"ОШИБКА: {e}"
|
147 |
+
try:
|
148 |
+
def bytes_convert(size_bytes):
|
149 |
+
if size_bytes >= 1073741824:
|
150 |
+
return f"{round(size_bytes / 1073741824, 2)} Гб"
|
151 |
+
else:
|
152 |
+
return f"{round(size_bytes / 1048576, 2)} Мб"
|
153 |
+
|
154 |
+
def downloader(url):
|
155 |
+
process = subprocess.Popen(url, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
156 |
+
while True:
|
157 |
+
output = process.stdout.readline().decode('utf-8')
|
158 |
+
if output == '' and process.poll() is not None:
|
159 |
+
break
|
160 |
+
if output:
|
161 |
+
yield output.strip()
|
162 |
+
return process.poll()
|
163 |
+
|
164 |
+
total_file_size = 0
|
165 |
+
with ThreadPoolExecutor(max_workers=len(urls)) as executor:
|
166 |
+
futures = [executor.submit(get_file_size, url) for url in urls]
|
167 |
+
for future in as_completed(futures):
|
168 |
+
total_file_size += future.result()
|
169 |
+
total, used, free = shutil.disk_usage(find_mount_point())
|
170 |
+
if total_file_size <= (free - 1073741824):
|
171 |
+
print(f"загрузка {bytes_convert(total_file_size)} уже началась, жди!")
|
172 |
+
with ThreadPoolExecutor(max_workers=len(urls)) as executor:
|
173 |
+
futures = [executor.submit(downloader, url) for url in urls]
|
174 |
+
for future in as_completed(futures):
|
175 |
+
for line in future.result():
|
176 |
+
print(line)
|
177 |
+
if os.path.exists(os.path.join(models_folder_path, "nullModel.ckpt")):
|
178 |
+
try:
|
179 |
+
os.remove(os.path.join(models_folder_path, "nullModel.ckpt"))
|
180 |
+
except:
|
181 |
+
pass
|
182 |
+
return "функция загрузки завершила работу!"
|
183 |
+
else:
|
184 |
+
print(f"слишком много файлов! ты пытаешься скачать {bytes_convert(total_file_size)}, имея свободных только {bytes_convert(free)} (и как минимум 1 Гб должен оставаться не занятым на диске!).")
|
185 |
+
return f"слишком много файлов! ты пытаешься скачать {bytes_convert(total_file_size)}, имея свободных только {bytes_convert(free)} (и как минимум 1 Гб должен оставаться не занятым на диске!)."
|
186 |
+
except Exception as e:
|
187 |
+
print(f"ОШИБКА: {e}")
|
188 |
+
return f"ОШИБКА: {e}"
|
189 |
+
|
190 |
+
# скрытый текстбокс для вывода информации о результате
|
191 |
+
dlresultbox = gr.Textbox(label="", elem_id="dlresultbox")
|
192 |
+
download_button.click(start_download, inputs=checkbox_groups, outputs=dlresultbox)
|
193 |
+
# анимация процесса выполнения функции загрузки
|
194 |
+
gr.HTML(
|
195 |
+
"""<div class="downloads_result_container"><div class="models_porgress_loader"></div><div id="downloads_start_text">задача по загрузке запущена, подробности в выводе ячейки в колабе...</div><div id="downloads_result_text"><span class="finish_dl_func"></span><span class="dl_progress_info"></span></div></div>""")
|
196 |
+
# скрытые элементы для взаимодействия с функцией определения места на диске
|
197 |
+
spacetextbox = gr.Textbox(label="", elem_id="free_space_area")
|
198 |
+
space_button = gr.Button("проверить свободное место", elem_id="free_space_button")
|
199 |
+
space_button.click(fn=free_space, outputs=spacetextbox)
|
200 |
+
# HTML-разметка для формирования чекбоксов для удаления файлов моделей
|
201 |
+
gr.HTML(
|
202 |
+
"""<hr class="divider"/><div id="filemanager"><h2 class="current_models_files">файлы моделей которые можно удалить для освобождения места:</h2><div id="files_checkbox"></div><div class="filebuttons"><div id="delete_files_button"></div><div id="refresh_files_button"></div></div></div>""")
|
203 |
+
|
204 |
+
# функция получения путей до установленных файлов моделей
|
205 |
+
def get_models_paths():
|
206 |
+
file_paths = []
|
207 |
+
for root, dirs, files in os.walk(models_folder_path):
|
208 |
+
for file in files:
|
209 |
+
file_path = os.path.join(root, file)
|
210 |
+
file_paths.append(file_path)
|
211 |
+
return '\n'.join(file_paths)
|
212 |
+
|
213 |
+
# скрытые текстбокс и кнопка для получения списка файлов из папки моделей
|
214 |
+
filestextbox = gr.Textbox(label="", elem_id="files_area")
|
215 |
+
files_button = gr.Button("установленные модели", elem_id="files_button")
|
216 |
+
files_button.click(fn=get_models_paths, outputs=filestextbox)
|
217 |
+
|
218 |
+
# функция удаления списка отмеченных файлов
|
219 |
+
def del_models(inputs):
|
220 |
+
files_to_delete = inputs.split("\n")
|
221 |
+
for file in files_to_delete:
|
222 |
+
if file and file != "None":
|
223 |
+
try:
|
224 |
+
os.remove(os.path.join(models_folder_path, file))
|
225 |
+
print(f"успешно удалена модель: {file}")
|
226 |
+
except OSError as e:
|
227 |
+
print(f"ОШИБКА: {e.filename} - {e.strerror}.")
|
228 |
+
else:
|
229 |
+
print("удалять нечего, или ничего не выбрано для удаления")
|
230 |
+
|
231 |
+
# скрытые текстбокс и кнопка для формирования списка файлов на удаление
|
232 |
+
deletetextbox = gr.Textbox(label="", elem_id="delete_area")
|
233 |
+
delete_button = gr.Button("удалить", elem_id="delete_button")
|
234 |
+
delete_button.click(fn=del_models, inputs=deletetextbox, outputs=deletetextbox)
|
235 |
+
with gr.Accordion("описания моделей (не обновляется)", open=False):
|
236 |
+
gr.HTML(requests.get("https://raw.githubusercontent.com/PR0LAPSE/PR0LAPSE.github.io/main/models.html").text)
|
237 |
+
# возврат всех элементов
|
238 |
+
return (models_list, "модели", "models_list"),
|
239 |
+
|
240 |
+
|
241 |
+
# вывод в вебуи
|
242 |
+
script_callbacks.on_ui_tabs(on_ui_tabs)
|
style.css
ADDED
@@ -0,0 +1,302 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#free_space_area,
|
2 |
+
#free_space_button,
|
3 |
+
#files_area,
|
4 |
+
#delete_area,
|
5 |
+
#files_button,
|
6 |
+
#delete_button,
|
7 |
+
#ownlinks_download_button,
|
8 |
+
#checkboxes_download_button,
|
9 |
+
#dlresultbox,
|
10 |
+
#downloads_result_text,
|
11 |
+
#downloads_start_text,
|
12 |
+
.models_porgress_loader {
|
13 |
+
display: none !important;
|
14 |
+
}
|
15 |
+
#models_search_input {
|
16 |
+
width: 500px !important;
|
17 |
+
float: none !important;
|
18 |
+
display: inline !important;
|
19 |
+
position: relative;
|
20 |
+
top: -25px;
|
21 |
+
}
|
22 |
+
#clear_search_models_results {
|
23 |
+
display: inline-block;
|
24 |
+
cursor: pointer !important;
|
25 |
+
--wh: 40px;
|
26 |
+
width: var(--wh);
|
27 |
+
height: var(--wh);
|
28 |
+
padding-top: 0px !important;
|
29 |
+
margin: 10px 0 0 10px!important;
|
30 |
+
position: relative;
|
31 |
+
top: -10px;
|
32 |
+
border-radius: 5px;
|
33 |
+
border: var(--button-border-width) solid var(--button-secondary-border-color);
|
34 |
+
text-align: center;
|
35 |
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40'%3E%3Cpath d='m9.02,30.98L30.98,9.02m0,21.96L9.02,9.02' fill='none' opacity='.5' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.17'/%3E%3C/svg%3E");
|
36 |
+
background-color: var(--button-secondary-background-fill);
|
37 |
+
}
|
38 |
+
#finded_models {
|
39 |
+
position: absolute;
|
40 |
+
z-index: 2;
|
41 |
+
width: 500px;
|
42 |
+
top: 50px;
|
43 |
+
background: var(--input-background-fill);
|
44 |
+
color: var(--body-text-color);
|
45 |
+
}
|
46 |
+
#finded_models label {
|
47 |
+
background: none !important;
|
48 |
+
border: none;
|
49 |
+
}
|
50 |
+
#tab_models_list .tabs label {
|
51 |
+
background: none !important;
|
52 |
+
border: none;
|
53 |
+
}
|
54 |
+
#tab_models_list .tabs .tabitem div fieldset div {
|
55 |
+
display: grid;
|
56 |
+
grid-gap: 10px;
|
57 |
+
}
|
58 |
+
#tab_models_list div[data-testid='checkbox-group'] label span {
|
59 |
+
width: 275px;
|
60 |
+
font-size: 0.92em !important;
|
61 |
+
white-space: nowrap;
|
62 |
+
overflow: hidden;
|
63 |
+
text-overflow: ellipsis;
|
64 |
+
}
|
65 |
+
#tab_models_list div.tab-nav > button {
|
66 |
+
font-size: 1em !important;
|
67 |
+
}
|
68 |
+
#tab_models_list fieldset label:hover:not(.selected) {
|
69 |
+
color: var(--checkbox-background-color-selected)!important;
|
70 |
+
}
|
71 |
+
#tab_models_list fieldset .selected {
|
72 |
+
color: #60d43d !important;
|
73 |
+
}
|
74 |
+
#general_download_button {
|
75 |
+
border: var(--button-border-width) solid var(--button-primary-border-color);
|
76 |
+
background: var(--button-primary-background-fill);
|
77 |
+
color: var(--button-primary-text-color);
|
78 |
+
margin-top: 28px !important;
|
79 |
+
}
|
80 |
+
#tab_models_list button.secondary {
|
81 |
+
width: 70%;
|
82 |
+
margin: 0 auto;
|
83 |
+
}
|
84 |
+
#male_only {
|
85 |
+
color: #b8dabb !important;
|
86 |
+
}
|
87 |
+
.freespaceinfo {
|
88 |
+
width: fit-content;
|
89 |
+
display: flex;
|
90 |
+
flex-direction: row;
|
91 |
+
flex-wrap: nowrap;
|
92 |
+
justify-content: flex-start;
|
93 |
+
align-items: center;
|
94 |
+
}
|
95 |
+
#frespace_output {
|
96 |
+
width: fit-content;
|
97 |
+
height: 40px;
|
98 |
+
border: 1px solid var(--button-secondary-border-color);
|
99 |
+
margin: -30px 0px 0px 0px;
|
100 |
+
display: flex;
|
101 |
+
flex-direction: row;
|
102 |
+
flex-wrap: nowrap;
|
103 |
+
align-items: center;
|
104 |
+
padding: 0px 15px;
|
105 |
+
font-size: 1.2em;
|
106 |
+
}
|
107 |
+
#freespace_get {
|
108 |
+
width: 40px;
|
109 |
+
height: 40px;
|
110 |
+
border: 1px solid var(--button-secondary-border-color);
|
111 |
+
margin: -30px 50px 0px 10px;
|
112 |
+
cursor: pointer;
|
113 |
+
background-image: url("data:image/svg+xml,%3Csvg id='refresh' xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 36 36'%3E%3Cpath fill='%23fff' opacity='.5' d='m3.33,33v-2.81h6.09l-.7-.56c-2-1.59-3.45-3.33-4.36-5.2-.91-1.88-1.36-3.97-1.36-6.28,0-3.31.98-6.29,2.93-8.93,1.95-2.64,4.52-4.46,7.71-5.46v2.91c-2.34.91-4.23,2.41-5.67,4.52-1.44,2.11-2.16,4.43-2.16,6.96,0,1.97.37,3.68,1.1,5.13.73,1.45,1.73,2.71,2.98,3.77l1.41.98v-5.81h2.81v10.78H3.33Zm19.08-.7v-2.95c2.37-.91,4.27-2.41,5.67-4.52,1.41-2.11,2.11-4.43,2.11-6.96,0-1.5-.37-3.02-1.1-4.57-.73-1.55-1.7-2.91-2.88-4.1l-1.36-1.22v5.81h-2.81V3h10.78v2.81h-6.14l.7.66c1.88,1.75,3.28,3.63,4.22,5.63.94,2,1.41,3.92,1.41,5.77,0,3.31-.97,6.3-2.91,8.95-1.94,2.66-4.5,4.48-7.69,5.48Z'%3E%3C/path%3E%3C/svg%3E");
|
114 |
+
background-position: 50%;
|
115 |
+
background-repeat: no-repeat
|
116 |
+
}
|
117 |
+
#freespace_get:hover {
|
118 |
+
background-color: #00000078;
|
119 |
+
background-image: url("data:image/svg+xml,%3Csvg id='refresh' xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 36 36'%3E%3Cpath fill='%23fff' opacity='.7' d='m3.33,33v-2.81h6.09l-.7-.56c-2-1.59-3.45-3.33-4.36-5.2-.91-1.88-1.36-3.97-1.36-6.28,0-3.31.98-6.29,2.93-8.93,1.95-2.64,4.52-4.46,7.71-5.46v2.91c-2.34.91-4.23,2.41-5.67,4.52-1.44,2.11-2.16,4.43-2.16,6.96,0,1.97.37,3.68,1.1,5.13.73,1.45,1.73,2.71,2.98,3.77l1.41.98v-5.81h2.81v10.78H3.33Zm19.08-.7v-2.95c2.37-.91,4.27-2.41,5.67-4.52,1.41-2.11,2.11-4.43,2.11-6.96,0-1.5-.37-3.02-1.1-4.57-.73-1.55-1.7-2.91-2.88-4.1l-1.36-1.22v5.81h-2.81V3h10.78v2.81h-6.14l.7.66c1.88,1.75,3.28,3.63,4.22,5.63.94,2,1.41,3.92,1.41,5.77,0,3.31-.97,6.3-2.91,8.95-1.94,2.66-4.5,4.48-7.69,5.48Z'%3E%3C/path%3E%3C/svg%3E");
|
120 |
+
}
|
121 |
+
#freespace_get:active {
|
122 |
+
background-color: #00000078;
|
123 |
+
background-image: url("data:image/svg+xml,%3Csvg id='refresh' xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 36 36'%3E%3Cpath fill='%23fff' opacity='.85' d='m3.33,33v-2.81h6.09l-.7-.56c-2-1.59-3.45-3.33-4.36-5.2-.91-1.88-1.36-3.97-1.36-6.28,0-3.31.98-6.29,2.93-8.93,1.95-2.64,4.52-4.46,7.71-5.46v2.91c-2.34.91-4.23,2.41-5.67,4.52-1.44,2.11-2.16,4.43-2.16,6.96,0,1.97.37,3.68,1.1,5.13.73,1.45,1.73,2.71,2.98,3.77l1.41.98v-5.81h2.81v10.78H3.33Zm19.08-.7v-2.95c2.37-.91,4.27-2.41,5.67-4.52,1.41-2.11,2.11-4.43,2.11-6.96,0-1.5-.37-3.02-1.1-4.57-.73-1.55-1.7-2.91-2.88-4.1l-1.36-1.22v5.81h-2.81V3h10.78v2.81h-6.14l.7.66c1.88,1.75,3.28,3.63,4.22,5.63.94,2,1.41,3.92,1.41,5.77,0,3.31-.97,6.3-2.91,8.95-1.94,2.66-4.5,4.48-7.69,5.48Z'%3E%3C/path%3E%3C/svg%3E");
|
124 |
+
transform: rotate(90deg)
|
125 |
+
}
|
126 |
+
span#frespace_out {
|
127 |
+
color: #7ced7c
|
128 |
+
}
|
129 |
+
.ownfiles_header {
|
130 |
+
display: flex;
|
131 |
+
}
|
132 |
+
.ownfiles_header > span {
|
133 |
+
margin-right: 50px;
|
134 |
+
}
|
135 |
+
.ownfiles_header h2 {
|
136 |
+
font-size: 1.2em !important;
|
137 |
+
color: #deeedb !important;
|
138 |
+
font-weight: normal !important
|
139 |
+
}
|
140 |
+
#ownmodels > label > span {
|
141 |
+
color: #37e46f;
|
142 |
+
}
|
143 |
+
#ownloras > label > span {
|
144 |
+
color: #45b9ec;
|
145 |
+
}
|
146 |
+
#ownembeddings > label > span {
|
147 |
+
color: #f46ea2;
|
148 |
+
}
|
149 |
+
#ownmodels > label > textarea,
|
150 |
+
#ownloras > label > textarea,
|
151 |
+
#ownembeddings > label > textarea {
|
152 |
+
font-family: monospace;
|
153 |
+
font-size: 0.95em
|
154 |
+
}
|
155 |
+
#ownmodels > label > textarea {
|
156 |
+
color: #a7d0b4;
|
157 |
+
}
|
158 |
+
#ownloras > label > textarea {
|
159 |
+
color: #9bc5d9;
|
160 |
+
}
|
161 |
+
#ownembeddings > label > textarea {
|
162 |
+
color: #dcbfcb;
|
163 |
+
}
|
164 |
+
#filemanager {
|
165 |
+
height: max-content;
|
166 |
+
}
|
167 |
+
.current_models_files {
|
168 |
+
margin-bottom: 30px!important;
|
169 |
+
color: #eedbdb !important;
|
170 |
+
}
|
171 |
+
#files_checkbox {
|
172 |
+
width: max-content;
|
173 |
+
display: grid;
|
174 |
+
grid-template-columns: repeat(3, 1fr);
|
175 |
+
grid-gap: 35px;
|
176 |
+
grid-row-gap: 18px;
|
177 |
+
}
|
178 |
+
.filecheckbox input {
|
179 |
+
margin-right: 6px;
|
180 |
+
border: var(--checkbox-border-width) solid var(--checkbox-border-color) !important;
|
181 |
+
background-color: var(--checkbox-background-color) !important;
|
182 |
+
line-height: var(--line-sm) !important;
|
183 |
+
}
|
184 |
+
.filecheckbox input:checked {
|
185 |
+
border-color: #f47373 !important;
|
186 |
+
background-image: #de2f2f !important;
|
187 |
+
background-color: #de2f2f !important;
|
188 |
+
}
|
189 |
+
.filecheckbox span:hover {
|
190 |
+
color: #ff9494
|
191 |
+
}
|
192 |
+
.filebuttons {
|
193 |
+
display: flex;
|
194 |
+
flex-direction: row;
|
195 |
+
flex-wrap: wrap;
|
196 |
+
align-content: center;
|
197 |
+
align-items: center;
|
198 |
+
justify-content: center;
|
199 |
+
margin-top: 15px;
|
200 |
+
padding-top: 15px;
|
201 |
+
border-top: 2px solid #afafaf17;
|
202 |
+
}
|
203 |
+
#delete_files_button,
|
204 |
+
#refresh_files_button {
|
205 |
+
width: 40px;
|
206 |
+
height: 40px;
|
207 |
+
border: 1px solid var(--button-secondary-border-color);
|
208 |
+
margin: 0 50px;
|
209 |
+
cursor: pointer;
|
210 |
+
background-color: transparent;
|
211 |
+
background-position: 50%;
|
212 |
+
background-repeat: no-repeat
|
213 |
+
}
|
214 |
+
#refresh_files_button {
|
215 |
+
background-image: url("data:image/svg+xml,%3Csvg id='refresh' xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 36 36'%3E%3Cpath fill='%23fff' opacity='.5' d='m3.33,33v-2.81h6.09l-.7-.56c-2-1.59-3.45-3.33-4.36-5.2-.91-1.88-1.36-3.97-1.36-6.28,0-3.31.98-6.29,2.93-8.93,1.95-2.64,4.52-4.46,7.71-5.46v2.91c-2.34.91-4.23,2.41-5.67,4.52-1.44,2.11-2.16,4.43-2.16,6.96,0,1.97.37,3.68,1.1,5.13.73,1.45,1.73,2.71,2.98,3.77l1.41.98v-5.81h2.81v10.78H3.33Zm19.08-.7v-2.95c2.37-.91,4.27-2.41,5.67-4.52,1.41-2.11,2.11-4.43,2.11-6.96,0-1.5-.37-3.02-1.1-4.57-.73-1.55-1.7-2.91-2.88-4.1l-1.36-1.22v5.81h-2.81V3h10.78v2.81h-6.14l.7.66c1.88,1.75,3.28,3.63,4.22,5.63.94,2,1.41,3.92,1.41,5.77,0,3.31-.97,6.3-2.91,8.95-1.94,2.66-4.5,4.48-7.69,5.48Z'%3E%3C/path%3E%3C/svg%3E");
|
216 |
+
}
|
217 |
+
#refresh_files_button:hover {
|
218 |
+
background-color: #00000078;
|
219 |
+
background-image: url("data:image/svg+xml,%3Csvg id='refresh' xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 36 36'%3E%3Cpath fill='%23fff' opacity='.7' d='m3.33,33v-2.81h6.09l-.7-.56c-2-1.59-3.45-3.33-4.36-5.2-.91-1.88-1.36-3.97-1.36-6.28,0-3.31.98-6.29,2.93-8.93,1.95-2.64,4.52-4.46,7.71-5.46v2.91c-2.34.91-4.23,2.41-5.67,4.52-1.44,2.11-2.16,4.43-2.16,6.96,0,1.97.37,3.68,1.1,5.13.73,1.45,1.73,2.71,2.98,3.77l1.41.98v-5.81h2.81v10.78H3.33Zm19.08-.7v-2.95c2.37-.91,4.27-2.41,5.67-4.52,1.41-2.11,2.11-4.43,2.11-6.96,0-1.5-.37-3.02-1.1-4.57-.73-1.55-1.7-2.91-2.88-4.1l-1.36-1.22v5.81h-2.81V3h10.78v2.81h-6.14l.7.66c1.88,1.75,3.28,3.63,4.22,5.63.94,2,1.41,3.92,1.41,5.77,0,3.31-.97,6.3-2.91,8.95-1.94,2.66-4.5,4.48-7.69,5.48Z'%3E%3C/path%3E%3C/svg%3E");
|
220 |
+
}
|
221 |
+
#refresh_files_button:active {
|
222 |
+
background-color: #00000078;
|
223 |
+
background-image: url("data:image/svg+xml,%3Csvg id='refresh' xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 36 36'%3E%3Cpath fill='%23fff' opacity='.85' d='m3.33,33v-2.81h6.09l-.7-.56c-2-1.59-3.45-3.33-4.36-5.2-.91-1.88-1.36-3.97-1.36-6.28,0-3.31.98-6.29,2.93-8.93,1.95-2.64,4.52-4.46,7.71-5.46v2.91c-2.34.91-4.23,2.41-5.67,4.52-1.44,2.11-2.16,4.43-2.16,6.96,0,1.97.37,3.68,1.1,5.13.73,1.45,1.73,2.71,2.98,3.77l1.41.98v-5.81h2.81v10.78H3.33Zm19.08-.7v-2.95c2.37-.91,4.27-2.41,5.67-4.52,1.41-2.11,2.11-4.43,2.11-6.96,0-1.5-.37-3.02-1.1-4.57-.73-1.55-1.7-2.91-2.88-4.1l-1.36-1.22v5.81h-2.81V3h10.78v2.81h-6.14l.7.66c1.88,1.75,3.28,3.63,4.22,5.63.94,2,1.41,3.92,1.41,5.77,0,3.31-.97,6.3-2.91,8.95-1.94,2.66-4.5,4.48-7.69,5.48Z'%3E%3C/path%3E%3C/svg%3E");
|
224 |
+
transform: rotate(90deg)
|
225 |
+
}
|
226 |
+
#delete_files_button {
|
227 |
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='36' viewBox='0 0 32 36'%3E%3Cpath d='m10.05,27.05l5.95-6.05,6,6.05,2.35-2.4-5.95-6.05,5.95-6.05-2.35-2.4-6,6.05-5.95-6.05-2.4,2.4,6,6.05-6,6.05,2.4,2.4Zm-5,8.95c-.8,0-1.5-.3-2.1-.9s-.9-1.3-.9-2.1V4.5H0V1.5h9.4V0h13.2v1.5h9.4v3h-2.05v28.5c0,.8-.3,1.5-.9,2.1s-1.3.9-2.1.9H5.05ZM26.95,4.5H5.05v28.5h21.9V4.5Zm-21.9,0v28.5V4.5Z' opacity='.5' fill='%23fff'/%3E%3C/svg%3E");
|
228 |
+
background-size: 62%;
|
229 |
+
}
|
230 |
+
#delete_files_button:hover {
|
231 |
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='36' viewBox='0 0 32 36'%3E%3Cpath d='m10.05,27.05l5.95-6.05,6,6.05,2.35-2.4-5.95-6.05,5.95-6.05-2.35-2.4-6,6.05-5.95-6.05-2.4,2.4,6,6.05-6,6.05,2.4,2.4Zm-5,8.95c-.8,0-1.5-.3-2.1-.9s-.9-1.3-.9-2.1V4.5H0V1.5h9.4V0h13.2v1.5h9.4v3h-2.05v28.5c0,.8-.3,1.5-.9,2.1s-1.3.9-2.1.9H5.05ZM26.95,4.5H5.05v28.5h21.9V4.5Zm-21.9,0v28.5V4.5Z' opacity='.7' fill='%23ff2727'/%3E%3C/svg%3E");
|
232 |
+
background-size: 62%;
|
233 |
+
}
|
234 |
+
#delete_files_button:active {
|
235 |
+
background-color: #00000078;
|
236 |
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='36' viewBox='0 0 32 36'%3E%3Cpath d='m10.05,27.05l5.95-6.05,6,6.05,2.35-2.4-5.95-6.05,5.95-6.05-2.35-2.4-6,6.05-5.95-6.05-2.4,2.4,6,6.05-6,6.05,2.4,2.4Zm-5,8.95c-.8,0-1.5-.3-2.1-.9s-.9-1.3-.9-2.1V4.5H0V1.5h9.4V0h13.2v1.5h9.4v3h-2.05v28.5c0,.8-.3,1.5-.9,2.1s-1.3.9-2.1.9H5.05ZM26.95,4.5H5.05v28.5h21.9V4.5Zm-21.9,0v28.5V4.5Z' opacity='1' fill='%23ff2727'/%3E%3C/svg%3E");
|
237 |
+
background-size: 62%;
|
238 |
+
}
|
239 |
+
.models_porgress_loader {
|
240 |
+
width: 70%;
|
241 |
+
height: 8px;
|
242 |
+
display: block;
|
243 |
+
background: var(--block-label-border-color);
|
244 |
+
position: relative;
|
245 |
+
top: 0px;
|
246 |
+
overflow: hidden;
|
247 |
+
margin: 0 auto;
|
248 |
+
}
|
249 |
+
.models_porgress_loader::after {
|
250 |
+
content: '';
|
251 |
+
width: 0%;
|
252 |
+
height: 8px;
|
253 |
+
background-color: #ffffff2e;
|
254 |
+
background-image: linear-gradient(45deg, rgba(0, 0, 0, .25) 25%, transparent 25%, transparent 50%, rgba(0, 0, 0, 0.25) 50%, rgba(0, 0, 0, 0.25) 75%, transparent 75%, transparent);
|
255 |
+
background-size: 15px 15px;
|
256 |
+
position: absolute;
|
257 |
+
top: 0;
|
258 |
+
left: 0;
|
259 |
+
box-sizing: border-box;
|
260 |
+
animation: models_progress_bar_anim 10s cubic-bezier(0.45, 0.05, 0.55, 0.95) infinite;
|
261 |
+
}
|
262 |
+
@keyframes models_progress_bar_anim {
|
263 |
+
0% {
|
264 |
+
width: 0;
|
265 |
+
}
|
266 |
+
100% {
|
267 |
+
width: 100%;
|
268 |
+
}
|
269 |
+
}
|
270 |
+
#downloads_result_text,
|
271 |
+
#downloads_start_text {
|
272 |
+
margin: 32px auto;
|
273 |
+
width: fit-content;
|
274 |
+
top: 100px;
|
275 |
+
font-size: 1.4em;
|
276 |
+
}
|
277 |
+
#downloads_start_text {
|
278 |
+
color: #81d0fb !important
|
279 |
+
}
|
280 |
+
#downloads_result_text > span {
|
281 |
+
display: block;
|
282 |
+
text-align: center;
|
283 |
+
}
|
284 |
+
#downloads_result_text > span.finish_dl_func {
|
285 |
+
color: #99fb99 !important
|
286 |
+
}
|
287 |
+
#downloads_result_text > span.dl_progress_info {
|
288 |
+
font-size: 0.7em!important;
|
289 |
+
margin-top: 10px;
|
290 |
+
}
|
291 |
+
#tab_models_list #colab_model_list.colab_model_list {
|
292 |
+
background: transparent !important;
|
293 |
+
background-image: none !important;
|
294 |
+
}
|
295 |
+
.request_new_models a {
|
296 |
+
color: var(--link-text-color) !important;
|
297 |
+
text-decoration: underline dashed !important
|
298 |
+
}
|
299 |
+
.request_new_models a:hover {
|
300 |
+
color: var(--link-text-color-hover) !important;
|
301 |
+
text-decoration: underline solid !important
|
302 |
+
}
|