2ch commited on
Commit
6272b9b
·
verified ·
1 Parent(s): b1c669d

Update scripts/colab_sd_models.py

Browse files
Files changed (1) hide show
  1. scripts/colab_sd_models.py +226 -217
scripts/colab_sd_models.py CHANGED
@@ -1,242 +1,251 @@
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)
 
 
 
 
 
 
1
  from concurrent.futures import ThreadPoolExecutor, as_completed
2
+ from pathlib import Path
3
+ from re import search
4
+ from shutil import disk_usage
5
+ from subprocess import PIPE, Popen, STDOUT, run
6
 
7
  import gradio as gr
8
+ from requests import get as requests_get, head as requests_head
9
+ from modules import script_callbacks, sd_models, shared
10
  from modules.paths_internal import data_path
11
 
12
 
13
+ DL_COMMAND = 'wget -nv -t 10 --show-progress --progress=bar:force -q --content-disposition "{link}" -P {dl_path}'
14
+ WEBUI_ROOT = Path(data_path)
15
+ LINKS_FILE = WEBUI_ROOT / 'links.txt'
16
+ MODELS_FOLDER_PATH = Path(sd_models.model_path)
17
+ LORAS_FOLDER_PATH = Path(shared.cmd_opts.lora_dir)
18
+ EMBEDDINGS_FOLDER_PATH = Path(shared.cmd_opts.embeddings_dir)
19
+ CIVITAI_TOKEN = '542c1d6077168822e1b49e30e3437a5d'
20
+
21
+
22
+ def del_null_model():
23
+ null_model_path = MODELS_FOLDER_PATH / 'nullModel.ckpt'
24
+ if null_model_path.exists():
25
+ try:
26
+ null_model_path.unlink(missing_ok=True)
27
+ except:
28
+ pass
29
+
30
+
31
+ def find_mount_point():
32
+ path = Path(__file__).resolve()
33
+ while not path.is_mount():
34
+ path = path.parent
35
+ return path
36
+
37
+
38
+ def free_space():
39
+ total, used, free = disk_usage(find_mount_point())
40
+ power = 2 ** 10
41
+ n = 0
42
+ power_labels = {0: '', 1: 'Кило', 2: 'Мега', 3: 'Гига', 4: 'Тера'}
43
+ while free > power:
44
+ free /= power
45
+ n += 1
46
+ return f'{free:.2f} {power_labels[n]}байт'
47
+
48
+
49
+ def extract_url(command_eith_url):
50
+ pattern = r'["\']?((?:https?|ftp|ftps)://[^\s"\'<>]+)["\']?'
51
+ match = search(pattern, command_eith_url)
52
+ return match.group(1) if match else None
53
+
54
+ def hf_size(url: str) -> int:
55
+ try:
56
+ modified_url = url.replace('resolve', 'raw')
57
+ response = requests_get(modified_url, timeout=10)
58
+ response.raise_for_status()
59
+ content = response.text
60
+ size_str = content.split('size')[-1].strip().split()[0]
61
+ return int(size_str) if size_str.isdigit() else 0
62
+ except:
63
+ return 0
64
+
65
+
66
+ def cv_size(url: str) -> int:
67
+ try:
68
+ model_version_id = url.split('/')[-1]
69
+ response = requests_get(f'https://civitai.com/api/v1/model-versions/{model_version_id}?token={CIVITAI_TOKEN}', timeout=10)
70
+ response.raise_for_status()
71
+ files = response.json().get('files', [])
72
+ if files:
73
+ size_kb = files[0].get('sizeKB', 0)
74
+ return int(size_kb * 1024)
75
+ return 0
76
+ except:
77
+ return 0
78
+
79
+
80
+ def get_file_size(command_with_url: str) -> int:
81
+ url = extract_url(command_with_url)
82
+ if not url:
83
+ print(f'в строке `{command_with_url}` ссылка не найдена')
84
+ return 0
85
+ file_size = 0
86
+ if 'huggingface' in url:
87
+ file_size = hf_size(url)
88
+ elif 'civitai' in url:
89
+ file_size = cv_size(url)
90
+ if file_size:
91
+ return file_size
92
+ try:
93
+ response = requests_head(url, allow_redirects=True, timeout=10)
94
+ response.raise_for_status()
95
+ content_length = response.headers.get('Content-Length')
96
+ if content_length and content_length.isdigit():
97
+ return int(content_length)
98
+ content_disposition = response.headers.get('Content-Disposition')
99
+ if content_disposition:
100
+ size_str = next((part.split('=')[1] for part in content_disposition.split(';') if 'size' in part), None)
101
+ if size_str and size_str.isdigit():
102
+ return int(size_str)
103
+ except Exception:
104
+ pass
105
+ try:
106
+ result = run(['curl', '-sI', url], capture_output=True, text=True)
107
+ if result.returncode == 0:
108
+ for line in result.stdout.splitlines():
109
+ if 'Content-Length' in line:
110
+ return int(line.split(':')[1].strip())
111
+ except Exception:
112
+ pass
113
+ try:
114
+ result = run(['wget', '--spider', '--server-response', url], capture_output=True, text=True)
115
+ if result.returncode == 0:
116
+ for line in result.stderr.splitlines():
117
+ if 'Content-Length' in line:
118
+ return int(line.split(':')[1].strip())
119
+ except Exception:
120
+ pass
121
+ return 0
122
+
123
+
124
+ def get_total_file_size(urls: list):
125
+ total_file_size = 0
126
+ with ThreadPoolExecutor(max_workers=len(urls)) as executor:
127
+ futures = [executor.submit(get_file_size, url) for url in urls]
128
+ for future in as_completed(futures):
129
+ total_file_size += future.result()
130
+ return total_file_size
131
+
132
+
133
+ def bytes_convert(size_bytes):
134
+ if size_bytes >= 1073741824:
135
+ return f'{round(size_bytes / 1073741824, 2)} Гб'
136
+ else:
137
+ return f'{round(size_bytes / 1048576, 2)} Мб'
138
+
139
+
140
+ def get_own_links(ownmodels, ownloras, ownembeddings):
141
+ dl_commands = []
142
+ for text, dlpath in zip([ownmodels, ownloras, ownembeddings], [MODELS_FOLDER_PATH, LORAS_FOLDER_PATH, EMBEDDINGS_FOLDER_PATH]):
143
+ lines = text.split('\n')
144
+ for line in lines:
145
+ if line.strip():
146
+ link = line.strip() + (f"?token={CIVITAI_TOKEN}" if "?" not in line else f"&token={CIVITAI_TOKEN}") if "civitai" in line else line.strip()
147
+ dl_command = DL_COMMAND.format(link=link, dl_path=dlpath.resolve().as_posix())
148
+ dl_commands.append(dl_command)
149
+ LINKS_FILE.write_text('\n'.join(dl_commands).strip(), encoding='utf-8')
150
+ print('список загрузки сформирован...')
151
+
152
+
153
+ def get_models_paths():
154
+ file_paths = []
155
+ for file in MODELS_FOLDER_PATH.rglob('*'):
156
+ if file.is_file():
157
+ file_paths.append(file.resolve().as_posix())
158
+ return '\n'.join(file_paths)
159
+
160
+
161
+ def del_models(inputs):
162
+ files_to_delete = inputs.split('\n')
163
+ for file in files_to_delete:
164
+ if file and file != 'None':
165
+ try:
166
+ (MODELS_FOLDER_PATH / file).unlink()
167
+ print(f'успешно удалена модель: {file}')
168
+ except OSError as e:
169
+ print(f'ОШИБКА: {e.filename} - {e.strerror}.')
170
+ else:
171
+ print('удалять нечего, или ничего не выбрано для удаления')
172
+
173
+
174
+ def downloader(command_with_url):
175
+ process = Popen(command_with_url, shell=True, stdout=PIPE, stderr=STDOUT)
176
+ while True:
177
+ output = process.stdout.readline().decode('utf-8')
178
+ if output == '' and process.poll() is not None:
179
+ break
180
+ if output:
181
+ yield output.strip()
182
+ return process.poll()
183
+
184
+
185
+ def parallel_download(command_with_url):
186
+ with ThreadPoolExecutor(max_workers=len(command_with_url)) as executor:
187
+ futures = [executor.submit(downloader, url) for url in command_with_url]
188
+ for future in as_completed(futures):
189
+ for line in future.result():
190
+ print(line)
191
 
192
 
193
  def on_ui_tabs():
194
  with gr.Blocks() as models_list:
 
195
  gr.HTML(
196
+ '<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>')
197
+ gr.HTML('<div class="ownfiles_header"><h2>здесь можно указать прямые ссылки на загрузку моделей, лор и внедрений</h2></div>')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  with gr.Row():
199
+ plhd = 'вставляй каждую ссылку с новой строки!\nпримеры ссылок:\nhttps://models.tensorplay.ai/104249\nhttps://civitai.com/api/download/models/110660\nhttps://huggingface.co/2ch/gay/resolve/main/lora/BettercocksFlaccid.safetensors'
200
  ownmodels = gr.Textbox(label="модели", placeholder=plhd, info="прямые ссылки на Checkpoints", lines=5, elem_id="ownmodels")
201
  ownloras = gr.Textbox(label="лоры", placeholder=plhd, info="прямые ссылки на LoRas", lines=5, elem_id="ownloras")
202
  ownembeddings = gr.Textbox(label="внедрения", placeholder=plhd, info="прямые ссылки на Textual Inversions", lines=5, elem_id="ownembeddings")
203
+
204
+ download_button = gr.Button('запустить загрузку', elem_id='general_download_button')
205
+ button = gr.Button('скачать по ссылкам', elem_id='ownlinks_download_button')
 
206
  button.click(get_own_links, inputs=[ownmodels, ownloras, ownembeddings])
207
+
208
+ download_button = gr.Button('скачать модели', elem_id='checkboxes_download_button')
209
+
210
+ def start_download():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
  try:
212
+ urls = LINKS_FILE.read_text(encoding='utf-8').splitlines()
213
+ LINKS_FILE.unlink(missing_ok=True)
214
+ total_file_size = get_total_file_size(urls)
215
+ total, used, free = disk_usage(find_mount_point())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
  if total_file_size <= (free - 1073741824):
217
+ print(f'загрузка {bytes_convert(total_file_size)} уже началась, жди!')
218
+ parallel_download(urls)
219
+ del_null_model()
220
+ return 'функция загрузки завершила работу!'
 
 
 
 
 
 
 
 
221
  else:
222
+ msg = f'слишком много файлов! ты пытаешься скачать {bytes_convert(total_file_size)}, имея свободных только {bytes_convert(free)} (и как минимум 1 Гб должен оставаться не занятым на диске!).'
223
+ print(msg)
224
+ return msg
225
  except Exception as e:
226
+ print(f'ОШИБКА: {e}')
227
+ return f'ОШИБКА: {e}'
228
 
229
+ dl_result_box = gr.Textbox(label='', elem_id='dlresultbox')
230
+ download_button.click(start_download, outputs=dl_result_box)
231
+
232
+ gr.HTML('<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>')
233
+
234
+ space_textbox = gr.Textbox(label="", elem_id="free_space_area")
 
 
235
  space_button = gr.Button("проверить свободное место", elem_id="free_space_button")
236
+ space_button.click(fn=free_space, outputs=space_textbox)
237
+
238
+ gr.HTML('<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>')
239
+
240
+ files_textbox = gr.Textbox(label='', elem_id='files_area')
241
+ files_button = gr.Button('установленные модели', elem_id='files_button')
242
+ files_button.click(fn=get_models_paths, outputs=files_textbox)
243
+
244
+ delete_textbox = gr.Textbox(label='', elem_id='delete_area')
245
+ delete_button = gr.Button('удалить', elem_id='delete_button')
246
+ delete_button.click(fn=del_models, inputs=delete_textbox, outputs=delete_textbox)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
 
248
+ return (models_list, 'модели', 'models_list'),
 
 
 
 
 
 
 
249
 
250
 
251
+ script_callbacks.on_ui_tabs(on_ui_tabs)