lang03383 commited on
Commit
d610ab3
·
verified ·
1 Parent(s): 43aee66

Upload folder using huggingface_hub

Browse files
files_cells/notebooks/en/auto_cleaner_en.ipynb ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "nbformat": 4,
3
+ "nbformat_minor": 0,
4
+ "metadata": {
5
+ "colab": {
6
+ "provenance": []
7
+ },
8
+ "kernelspec": {
9
+ "name": "python3",
10
+ "display_name": "Python 3"
11
+ },
12
+ "language_info": {
13
+ "name": "python"
14
+ }
15
+ },
16
+ "cells": [
17
+ {
18
+ "cell_type": "code",
19
+ "source": [
20
+ "##~ AutoCleaner V3.7 CODE | BY: ANXETY ~##\n",
21
+ "\n",
22
+ "from directory_setup import models_dir, vaes_dir, control_dir, loras_dir, output_dir\n",
23
+ "\n",
24
+ "import os\n",
25
+ "import time\n",
26
+ "from ipywidgets import widgets\n",
27
+ "from IPython.display import display, HTML, Javascript\n",
28
+ "\n",
29
+ "\n",
30
+ "# Setup Env\n",
31
+ "env = os.getenv('ENV_NAME')\n",
32
+ "root_path = os.getenv('ROOT_PATH')\n",
33
+ "webui_path = os.getenv('WEBUI_PATH')\n",
34
+ "free_plan = os.getenv('FREE_PLAN')\n",
35
+ "\n",
36
+ "\n",
37
+ "# ==================== CSS ====================\n",
38
+ "# Main CSS\n",
39
+ "css_file_path = f\"{root_path}/CSS/auto_cleaner.css\"\n",
40
+ "with open(css_file_path , \"r\") as f:\n",
41
+ " CSS_AC = f.read()\n",
42
+ "display(HTML(f\"<style>{CSS_AC}</style>\"))\n",
43
+ "\n",
44
+ "\n",
45
+ "# ================ AutoCleaner function ================\n",
46
+ "directories = {\n",
47
+ " \"Images\": output_dir,\n",
48
+ " \"Models\": models_dir,\n",
49
+ " \"Vae\": vaes_dir,\n",
50
+ " \"LoRa\": loras_dir,\n",
51
+ " \"ControlNet Models\": control_dir\n",
52
+ "}\n",
53
+ "\n",
54
+ "\"\"\" functions \"\"\"\n",
55
+ "def clean_directory(directory, directory_type):\n",
56
+ " deleted_files = 0\n",
57
+ "\n",
58
+ " for root, dirs, files in os.walk(directory):\n",
59
+ " for file in files:\n",
60
+ " file_path = os.path.join(root, file)\n",
61
+ "\n",
62
+ " if file.endswith(\".txt\"):\n",
63
+ " continue\n",
64
+ " if file.endswith((\".safetensors\", \".pt\")) or directory_type == \"Images\":\n",
65
+ " deleted_files += 1\n",
66
+ "\n",
67
+ " os.remove(file_path)\n",
68
+ " return deleted_files\n",
69
+ "\n",
70
+ "def update_memory_info():\n",
71
+ " disk_space = psutil.disk_usage(os.getcwd())\n",
72
+ " total = disk_space.total / (1024 ** 3)\n",
73
+ " used = disk_space.used / (1024 ** 3)\n",
74
+ " free = disk_space.free / (1024 ** 3)\n",
75
+ "\n",
76
+ " storage_info.value = f'''\n",
77
+ " <div class=\"storage_info_AC\">Total storage: {total:.2f} GB <span style=\"color: #555\">|</span> Used: {used:.2f} GB <span style=\"color: #555\">|</span> Free: {free:.2f} GB</div>\n",
78
+ " '''\n",
79
+ "\n",
80
+ "def on_execute_button_press(button):\n",
81
+ " selected_cleaners = auto_cleaner_widget.value\n",
82
+ " deleted_files_dict = {}\n",
83
+ "\n",
84
+ " for option in selected_cleaners:\n",
85
+ " if option in directories:\n",
86
+ " deleted_files_dict[option] = clean_directory(directories[option], option)\n",
87
+ "\n",
88
+ " output.clear_output()\n",
89
+ "\n",
90
+ " with output:\n",
91
+ " for message in generate_messages(deleted_files_dict):\n",
92
+ " message_widget = HTML(f'<p class=\"output_message_AC\">{message}</p>')\n",
93
+ " display(message_widget)\n",
94
+ "\n",
95
+ " update_memory_info()\n",
96
+ "\n",
97
+ "def on_clear_button_press(button):\n",
98
+ " container.add_class(\"hide\")\n",
99
+ " time.sleep(0.5)\n",
100
+ " widgets.Widget.close_all()\n",
101
+ "\n",
102
+ "def generate_messages(deleted_files_dict):\n",
103
+ " messages = []\n",
104
+ " word_variants = {\n",
105
+ " \"Images\": \"Images\",\n",
106
+ " \"Models\": \"Models\",\n",
107
+ " \"Vae\": \"Vae\",\n",
108
+ " \"LoRa\": \"LoRa\",\n",
109
+ " \"ControlNet Models\": \"ControlNet Models\"\n",
110
+ " }\n",
111
+ " for key, value in deleted_files_dict.items():\n",
112
+ " object_word = word_variants.get(key)\n",
113
+ " messages.append(f\"Deleted {value} {object_word}\")\n",
114
+ " return messages\n",
115
+ "# ================ AutoCleaner function ================\n",
116
+ "\n",
117
+ "\n",
118
+ "# --- storage memory ---\n",
119
+ "import psutil\n",
120
+ "disk_space = psutil.disk_usage(os.getcwd())\n",
121
+ "total = disk_space.total / (1024 ** 3)\n",
122
+ "used = disk_space.used / (1024 ** 3)\n",
123
+ "free = disk_space.free / (1024 ** 3)\n",
124
+ "\n",
125
+ "\n",
126
+ "# UI Code\n",
127
+ "AutoCleaner_options = AutoCleaner_options = list(directories.keys())\n",
128
+ "instruction_label = widgets.HTML('''\n",
129
+ "<span class=\"instruction_AC\">Use <span style=\"color: #B2B2B2;\">ctrl</span> or <span style=\"color: #B2B2B2;\">shift</span> for multiple selections.</span>\n",
130
+ "''')\n",
131
+ "auto_cleaner_widget = widgets.SelectMultiple(options=AutoCleaner_options, layout=widgets.Layout(width='auto')).add_class(\"custom-select-multiple_AC\")\n",
132
+ "output = widgets.Output().add_class(\"output_AC\")\n",
133
+ "# ---\n",
134
+ "execute_button = widgets.Button(description='Execute Cleaning').add_class(\"button_execute_AC\").add_class(\"button_AC\")\n",
135
+ "execute_button.on_click(on_execute_button_press)\n",
136
+ "clear_button = widgets.Button(description='Hide Widget').add_class(\"button_clear_AC\").add_class(\"button_AC\")\n",
137
+ "clear_button.on_click(on_clear_button_press)\n",
138
+ "# ---\n",
139
+ "storage_info = widgets.HTML(f'''\n",
140
+ "<div class=\"storage_info_AC\">Total storage: {total:.2f} GB <span style=\"color: #555\">|</span> Used: {used:.2f} GB <span style=\"color: #555\">|</span> Free: {free:.2f} GB</div>\n",
141
+ "''')\n",
142
+ "# ---\n",
143
+ "buttons = widgets.HBox([execute_button, clear_button])\n",
144
+ "lower_information_panel = widgets.HBox([buttons, storage_info]).add_class(\"lower_information_panel_AC\")\n",
145
+ "\n",
146
+ "container = widgets.VBox([instruction_label, widgets.HTML('<hr>'), auto_cleaner_widget, output, widgets.HTML('<hr>'), lower_information_panel]).add_class(\"container_AC\")\n",
147
+ "\n",
148
+ "display(container)"
149
+ ],
150
+ "metadata": {
151
+ "id": "I22dFg7F2j3G"
152
+ },
153
+ "execution_count": null,
154
+ "outputs": []
155
+ }
156
+ ]
157
+ }
files_cells/notebooks/en/downloading_en.ipynb ADDED
@@ -0,0 +1,637 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "metadata": {
7
+ "id": "2lJmbqrs3Mu8"
8
+ },
9
+ "outputs": [],
10
+ "source": [
11
+ "##~ DOWNLOADING CODE | BY: ANXETY ~##\n",
12
+ "\n",
13
+ "from directory_setup import *\n",
14
+ "from models_data import model_list, vae_list, controlnet_list\n",
15
+ "\n",
16
+ "import os\n",
17
+ "import re\n",
18
+ "import time\n",
19
+ "import json\n",
20
+ "import shutil\n",
21
+ "import zipfile\n",
22
+ "import requests\n",
23
+ "import subprocess\n",
24
+ "from datetime import timedelta\n",
25
+ "from subprocess import getoutput\n",
26
+ "from IPython.utils import capture\n",
27
+ "from IPython.display import clear_output\n",
28
+ "from urllib.parse import urlparse, parse_qs\n",
29
+ "\n",
30
+ "\n",
31
+ "# Setup Env\n",
32
+ "env = os.getenv('ENV_NAME')\n",
33
+ "root_path = os.getenv('ROOT_PATH')\n",
34
+ "webui_path = os.getenv('WEBUI_PATH')\n",
35
+ "free_plan = os.getenv('FREE_PLAN')\n",
36
+ "\n",
37
+ "UI = os.getenv('SDW_UI')\n",
38
+ "OLD_UI = os.getenv('SDW_OLD_UI')\n",
39
+ "\n",
40
+ "os.chdir(root_path)\n",
41
+ "\n",
42
+ "\n",
43
+ "# ============ loading settings V4 =============\n",
44
+ "def load_settings(path):\n",
45
+ " if os.path.exists(path):\n",
46
+ " with open(path, 'r') as file:\n",
47
+ " return json.load(file)\n",
48
+ " return {}\n",
49
+ "\n",
50
+ "settings = load_settings(f'{root_path}/settings.json')\n",
51
+ "\n",
52
+ "VARIABLES = [\n",
53
+ " 'model', 'model_num', 'inpainting_model',\n",
54
+ " 'vae', 'vae_num', 'latest_webui', 'latest_exstensions',\n",
55
+ " 'change_webui', 'detailed_download', 'controlnet',\n",
56
+ " 'controlnet_num', 'commit_hash', 'huggingface_token',\n",
57
+ " 'ngrok_token', 'zrok_token', 'commandline_arguments',\n",
58
+ " 'Model_url', 'Vae_url', 'LoRA_url', 'Embedding_url',\n",
59
+ " 'Extensions_url', 'custom_file_urls'\n",
60
+ "]\n",
61
+ "\n",
62
+ "locals().update({key: settings.get(key) for key in VARIABLES})\n",
63
+ "\n",
64
+ "\n",
65
+ "# ================ LIBRARIES V2 ================\n",
66
+ "flag_file = f\"{root_path}/libraries_installed.txt\"\n",
67
+ "\n",
68
+ "if not os.path.exists(flag_file):\n",
69
+ " print(\"💿 Installing the libraries, it's going to take a while:\\n\")\n",
70
+ "\n",
71
+ " install_lib = {\n",
72
+ " # \"aria2\": \"apt -y install aria2\",\n",
73
+ " \"aria2\": \"pip install aria2\",\n",
74
+ " \"localtunnel\": \"npm install -g localtunnel\",\n",
75
+ " }\n",
76
+ " if controlnet != 'none':\n",
77
+ " install_lib[\"insightface\"] = \"pip install insightface\"\n",
78
+ "\n",
79
+ " additional_libs = {\n",
80
+ " \"Google Colab\": {\n",
81
+ " \"xformers\": \"pip install xformers==0.0.27 --no-deps\"\n",
82
+ " },\n",
83
+ " \"Kaggle\": {\n",
84
+ " \"xformers\": \"pip install xformers==0.0.26.post1\",\n",
85
+ " # \"torch\": \"pip install torch==2.1.2+cu121 torchvision==0.16.2+cu121 torchaudio==2.1.2 --extra-index-url https://download.pytorch.org/whl/cu121\",\n",
86
+ " # \"aiohttp\": \"pip install trash-cli && trash-put /opt/conda/lib/python3.10/site-packages/aiohttp*\" # fix install req\n",
87
+ " }\n",
88
+ " }\n",
89
+ " if env in additional_libs:\n",
90
+ " install_lib.update(additional_libs[env])\n",
91
+ "\n",
92
+ " # Loop through libraries\n",
93
+ " for index, (package, install_cmd) in enumerate(install_lib.items(), start=1):\n",
94
+ " print(f\"\\r[{index}/{len(install_lib)}] \\033[32m>>\\033[0m Installing \\033[33m{package}\\033[0m...\" + \" \"*35, end='')\n",
95
+ " subprocess.run(install_cmd, shell=True, capture_output=True)\n",
96
+ "\n",
97
+ " # Additional specific packages\n",
98
+ " with capture.capture_output():\n",
99
+ " !curl -s -OL https://github.com/DEX-1101/sd-webui-notebook/raw/main/res/new_tunnel --output-dir {root_path}\n",
100
+ " !curl -s -Lo /usr/bin/cl https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 && chmod +x /usr/bin/cl\n",
101
+ " !curl -sLO https://github.com/openziti/zrok/releases/download/v0.4.32/zrok_0.4.32_linux_amd64.tar.gz && tar -xzf zrok_0.4.32_linux_amd64.tar.gz -C /usr/bin && rm -f zrok_0.4.32_linux_amd64.tar.gz\n",
102
+ "\n",
103
+ " clear_output()\n",
104
+ "\n",
105
+ " # Save file install lib\n",
106
+ " with open(flag_file, \"w\") as f:\n",
107
+ " f.write(\">W<'\")\n",
108
+ "\n",
109
+ " print(\"🍪 Libraries are installed!\" + \" \"*35)\n",
110
+ " time.sleep(2)\n",
111
+ " clear_output()\n",
112
+ "\n",
113
+ "\n",
114
+ "# =================== OTHER ====================\n",
115
+ "# Setup Timer\n",
116
+ "start_colab = int(os.environ.get(\"START_COLAB\", time.time() - 5))\n",
117
+ "os.environ[\"START_COLAB\"] = str(start_colab)\n",
118
+ "\n",
119
+ "def download_cfg_files(file_paths, destination_path):\n",
120
+ " base_url = \"https://huggingface.co/NagisaNao/SD-CONFIGS/resolve/main\"\n",
121
+ " for filename in file_paths:\n",
122
+ " file_name = filename.split('/')[-1]\n",
123
+ " !wget -O {destination_path}/{file_name} {base_url}/{filename}\n",
124
+ "\n",
125
+ "def cfg_download():\n",
126
+ " common_files = [\"styles.csv\"]\n",
127
+ " a1111_files = [\"A1111/config.json\", \"A1111/ui-config.json\"]\n",
128
+ " forge_files = [\"reForge/config.json\", \"reForge/ui-config.json\"]\n",
129
+ "\n",
130
+ " with capture.capture_output():\n",
131
+ " download_cfg_files(common_files, webui_path)\n",
132
+ " ui_files = a1111_files if UI == 'A1111' else forge_files\n",
133
+ " download_cfg_files(ui_files, webui_path)\n",
134
+ "\n",
135
+ "def remove_dir(directory_path):\n",
136
+ " if directory_path and os.path.exists(directory_path):\n",
137
+ " try:\n",
138
+ " shutil.rmtree(directory_path)\n",
139
+ " except Exception:\n",
140
+ " !rm -rf {directory_path}\n",
141
+ "\n",
142
+ "TEMPORARY_DIR = f'{root_path}/temp_dir'\n",
143
+ "def copy_items_with_replace(src_base, dst_base):\n",
144
+ " items_to_copy = [\n",
145
+ " 'embeddings',\n",
146
+ " 'models/Stable-diffusion',\n",
147
+ " 'models/VAE',\n",
148
+ " 'models/Lora',\n",
149
+ " 'models/ControlNet'\n",
150
+ " ]\n",
151
+ "\n",
152
+ " print(\"⌚ Moving files...\", end='')\n",
153
+ " for item in items_to_copy:\n",
154
+ " src = os.path.join(src_base, item)\n",
155
+ " dst = os.path.join(dst_base, item)\n",
156
+ "\n",
157
+ " if os.path.exists(src):\n",
158
+ " if os.path.exists(dst):\n",
159
+ " remove_dir(dst)\n",
160
+ " os.makedirs(os.path.dirname(dst), exist_ok=True)\n",
161
+ " shutil.move(src, dst)\n",
162
+ " print(\"\\r🔥 Files moved!\" + \" \"*15)\n",
163
+ "\n",
164
+ "def handle_colab_timer(webui_path, timer_colab):\n",
165
+ " timer_file_path = os.path.join(webui_path, 'static', 'colabTimer.txt')\n",
166
+ " if not os.path.exists(timer_file_path):\n",
167
+ " with open(timer_file_path, 'w') as timer_file:\n",
168
+ " timer_file.write(str(timer_colab))\n",
169
+ " else:\n",
170
+ " with open(timer_file_path, 'r') as timer_file:\n",
171
+ " timer_colab = float(timer_file.read())\n",
172
+ " return timer_colab\n",
173
+ "\n",
174
+ "def unpack_webui():\n",
175
+ " start_install = time.time()\n",
176
+ " print(f\"⌚ Unpacking Stable Diffusion{' (Forge)' if UI == 'Forge' else ''}...\", end='')\n",
177
+ "\n",
178
+ " with capture.capture_output():\n",
179
+ " download_url = \"https://huggingface.co/NagisaNao/fast_repo/resolve/main/FULL_REPO.zip\"\n",
180
+ " if UI == 'Forge':\n",
181
+ " download_url = \"https://huggingface.co/NagisaNao/fast_repo/resolve/main/FULL_REPO_forge.zip\"\n",
182
+ "\n",
183
+ " zip_path = f\"{root_path}/repo.zip\"\n",
184
+ " !aria2c --console-log-level=error -c -x 16 -s 16 -k 1M {download_url} -d {root_path} -o repo.zip\n",
185
+ " !unzip -q -o {zip_path} -d {webui_path}\n",
186
+ " !rm -rf {zip_path}\n",
187
+ "\n",
188
+ " handle_colab_timer(webui_path, start_colab)\n",
189
+ "\n",
190
+ " install_time = time.time() - start_install\n",
191
+ " minutes, seconds = divmod(int(install_time), 60)\n",
192
+ " print(f\"\\r🚀 Unpacking complete! For {minutes:02}:{seconds:02} ⚡\" + \" \"*15)\n",
193
+ "\n",
194
+ " if os.path.exists(TEMPORARY_DIR):\n",
195
+ " copy_items_with_replace(TEMPORARY_DIR, webui_path)\n",
196
+ " remove_dir(TEMPORARY_DIR)\n",
197
+ "\n",
198
+ "# ================= MAIN CODE ==================\n",
199
+ "if os.path.exists(webui_path):\n",
200
+ " if UI != OLD_UI:\n",
201
+ " print(f'Switching the WebUI from \\033[33m{OLD_UI}\\033[0m to \\033[33m{UI}\\033[0m:')\n",
202
+ " copy_items_with_replace(webui_path, TEMPORARY_DIR)\n",
203
+ " remove_dir(webui_path)\n",
204
+ " os.environ['SDW_OLD_UI'] = UI\n",
205
+ " time.sleep(2)\n",
206
+ " clear_output()\n",
207
+ "\n",
208
+ "if not os.path.exists(webui_path):\n",
209
+ " unpack_webui()\n",
210
+ " cfg_download()\n",
211
+ "else:\n",
212
+ " print(\"🚀 All unpacked... Skip. ⚡\")\n",
213
+ " timer_colab = handle_colab_timer(webui_path, start_colab)\n",
214
+ " elapsed_time = str(timedelta(seconds=time.time() - timer_colab)).split('.')[0]\n",
215
+ " print(f\"⌚️ You have been conducting this session for - \\033[33m{elapsed_time}\\033[0m\")\n",
216
+ "\n",
217
+ "\n",
218
+ "## Changes extensions and WebUi\n",
219
+ "if latest_webui or latest_exstensions:\n",
220
+ " action = \"WebUI and Extensions\" if latest_webui and latest_exstensions else (\"WebUI\" if latest_webui else \"Extensions\")\n",
221
+ " print(f\"⌚️ Updating {action}...\", end='')\n",
222
+ " with capture.capture_output():\n",
223
+ " !git config --global user.email \"[email protected]\"\n",
224
+ " !git config --global user.name \"Your Name\"\n",
225
+ "\n",
226
+ " ## Update Webui\n",
227
+ " if latest_webui:\n",
228
+ " %cd {webui_path}\n",
229
+ " !git restore .\n",
230
+ " !git pull -X theirs --rebase --autostash\n",
231
+ "\n",
232
+ " ## Update extensions\n",
233
+ " if latest_exstensions:\n",
234
+ " !{'for dir in ' + webui_path + '/extensions/*/; do cd \\\"$dir\\\" && git reset --hard && git pull; done'}\n",
235
+ " print(f\"\\r✨ Updating {action} Completed!\")\n",
236
+ "\n",
237
+ "\n",
238
+ "# === FIXING EXTENSIONS ===\n",
239
+ "anxety_repos = \"https://huggingface.co/NagisaNao/fast_repo/resolve/main\"\n",
240
+ "with capture.capture_output():\n",
241
+ " # --- Umi-Wildcard ---\n",
242
+ " !sed -i '521s/open=\\(False\\|True\\)/open=False/' {webui_path}/extensions/Umi-AI-Wildcards/scripts/wildcard_recursive.py # Closed accordion by default\n",
243
+ " # --- Encrypt-Image ---\n",
244
+ " !sed -i '9,37d' {webui_path}/extensions/Encrypt-Image/javascript/encrypt_images_info.js # Removes the weird text in webui\n",
245
+ "\n",
246
+ "\n",
247
+ "## Version switching\n",
248
+ "if commit_hash:\n",
249
+ " print('⏳ Time machine activation...', end=\"\")\n",
250
+ " with capture.capture_output():\n",
251
+ " %cd {webui_path}\n",
252
+ " !git config --global user.email \"[email protected]\"\n",
253
+ " !git config --global user.name \"Your Name\"\n",
254
+ " !git reset --hard {commit_hash}\n",
255
+ " print(f\"\\r⌛️ The time machine has been activated! Current commit: \\033[34m{commit_hash}\\033[0m\")\n",
256
+ "\n",
257
+ "\n",
258
+ "## Downloading model and stuff | oh~ Hey! If you're freaked out by that code too, don't worry, me too!\n",
259
+ "print(\"📦 Downloading models and stuff...\", end='')\n",
260
+ "\n",
261
+ "extension_repo = []\n",
262
+ "PREFIXES = {\n",
263
+ " \"model\": models_dir,\n",
264
+ " \"vae\": vaes_dir,\n",
265
+ " \"lora\": loras_dir,\n",
266
+ " \"embed\": embeddings_dir,\n",
267
+ " \"extension\": extensions_dir,\n",
268
+ " \"control\": control_dir,\n",
269
+ " \"adetailer\": adetailer_dir,\n",
270
+ " \"config\": webui_path\n",
271
+ "}\n",
272
+ "!mkdir -p {\" \".join(PREFIXES.values())}\n",
273
+ "\n",
274
+ "''' Formatted Info Output '''\n",
275
+ "\n",
276
+ "def center_text(text, terminal_width=45):\n",
277
+ " padding = (terminal_width - len(text)) // 2\n",
278
+ " return f\"{' ' * padding}{text}{' ' * padding}\"\n",
279
+ "\n",
280
+ "def format_output(url, dst_dir, file_name, image_name=None, image_url=None):\n",
281
+ " info = center_text(f\"[{file_name.split('.')[0]}]\")\n",
282
+ " sep_line = '---' * 20\n",
283
+ "\n",
284
+ " print(f\"\\n\\033[32m{sep_line}\\033[36;1m{info}\\033[32m{sep_line}\\033[0m\")\n",
285
+ " print(f\"\\033[33mURL: {url}\")\n",
286
+ " print(f\"\\033[33mSAVE DIR: \\033[34m{dst_dir}\")\n",
287
+ " print(f\"\\033[33mFILE NAME: \\033[34m{file_name}\\033[0m\")\n",
288
+ " if 'civitai' in url and image_url:\n",
289
+ " print(f\"\\033[32m[Preview DL]:\\033[0m {image_name} - {image_url}\\n\")\n",
290
+ "\n",
291
+ "''' GET CivitAi API - DATA '''\n",
292
+ "\n",
293
+ "def CivitAi_API(url, file_name=None):\n",
294
+ " SUPPORT_TYPES = ('Checkpoint', 'TextualInversion', 'LORA')\n",
295
+ " CIVITAI_TOKEN = \"62c0c5956b2f9defbd844d754000180b\"\n",
296
+ "\n",
297
+ " url = url.split('?token=')[0] if '?token=' in url else url\n",
298
+ " url = url.replace('?type=', f'?token={CIVITAI_TOKEN}&type=') if '?type=' in url else f\"{url}?token={CIVITAI_TOKEN}\"\n",
299
+ "\n",
300
+ " def get_model_data(url):\n",
301
+ " base_url = \"https://civitai.com/api/v1\"\n",
302
+ " try:\n",
303
+ " if \"civitai.com/models/\" in url:\n",
304
+ " if '?modelVersionId=' in url:\n",
305
+ " version_id = url.split('?modelVersionId=')[1]\n",
306
+ " else:\n",
307
+ " model_id = url.split('/models/')[1].split('/')[0]\n",
308
+ " model_data = requests.get(f\"{base_url}/models/{model_id}\").json()\n",
309
+ " version_id = model_data['modelVersions'][0].get('id')\n",
310
+ " else:\n",
311
+ " version_id = url.split('/models/')[1].split('/')[0]\n",
312
+ "\n",
313
+ " return requests.get(f\"{base_url}/model-versions/{version_id}\").json()\n",
314
+ " except (KeyError, IndexError, requests.RequestException) as e:\n",
315
+ " return None\n",
316
+ "\n",
317
+ " data = get_model_data(url)\n",
318
+ "\n",
319
+ " if not data:\n",
320
+ " print(\"\\033[31m[Data Info]:\\033[0m Failed to retrieve data from the API.\\n\")\n",
321
+ " return 'None', None, None, None, None, None, None\n",
322
+ "\n",
323
+ " def get_model_info(url, data):\n",
324
+ " model_type = data['model']['type']\n",
325
+ " model_name = data['files'][0]['name']\n",
326
+ "\n",
327
+ " if 'type=' in url:\n",
328
+ " url_model_type = parse_qs(urlparse(url).query).get('type', [''])[0].lower()\n",
329
+ " if 'vae' in url_model_type:\n",
330
+ " model_type = data['files'][1]['type']\n",
331
+ " model_name = data['files'][1]['name']\n",
332
+ "\n",
333
+ " if file_name and '.' not in file_name:\n",
334
+ " file_extension = model_name.split('.')[-1]\n",
335
+ " model_name = f\"{file_name}.{file_extension}\"\n",
336
+ " elif file_name:\n",
337
+ " model_name = file_name\n",
338
+ "\n",
339
+ " return model_type, model_name\n",
340
+ "\n",
341
+ " def get_download_url(data, model_type):\n",
342
+ " if any(t.lower() in model_type.lower() for t in SUPPORT_TYPES):\n",
343
+ " return data['files'][0]['downloadUrl']\n",
344
+ "\n",
345
+ " return data['files'][1]['downloadUrl'] if 'type' in url else data['files'][0]['downloadUrl']\n",
346
+ "\n",
347
+ " def get_image_info(data, model_type, model_name):\n",
348
+ " if not any(t in model_type for t in SUPPORT_TYPES):\n",
349
+ " return None, None\n",
350
+ "\n",
351
+ " for image in data.get('images', []):\n",
352
+ " if image['nsfwLevel'] >= 4 and env == 'Kaggle': # Filter NSFW images for Kaggle\n",
353
+ " continue\n",
354
+ " image_url = image['url']\n",
355
+ " image_extension = image_url.split('.')[-1]\n",
356
+ " image_name = f\"{model_name.split('.')[0]}.preview.{image_extension}\" if image_url else None\n",
357
+ " return image_url, image_name\n",
358
+ " return None, None\n",
359
+ "\n",
360
+ " model_type, model_name = get_model_info(url, data)\n",
361
+ " download_url = get_download_url(data, model_type)\n",
362
+ " image_url, image_name = get_image_info(data, model_type, model_name)\n",
363
+ "\n",
364
+ " return f\"{download_url}{'&' if '?' in download_url else '?'}token={CIVITAI_TOKEN}\", download_url, model_type, model_name, image_url, image_name, data\n",
365
+ "\n",
366
+ "''' Main Download Code '''\n",
367
+ "\n",
368
+ "def strip_(url):\n",
369
+ " if 'github.com' in url:\n",
370
+ " return url.replace('/blob/', '/raw/')\n",
371
+ " elif \"huggingface.co\" in url:\n",
372
+ " url = url.replace('/blob/', '/resolve/')\n",
373
+ " return url.split('?')[0] if '?' in url else url\n",
374
+ " return url\n",
375
+ "\n",
376
+ "def download(url):\n",
377
+ " links_and_paths = [link_or_path.strip() for link_or_path in url.split(',') if link_or_path.strip()]\n",
378
+ "\n",
379
+ " for link_or_path in links_and_paths:\n",
380
+ " if any(link_or_path.lower().startswith(prefix) for prefix in PREFIXES):\n",
381
+ " handle_manual(link_or_path)\n",
382
+ " else:\n",
383
+ " url, dst_dir, file_name = link_or_path.split()\n",
384
+ " manual_download(url, dst_dir, file_name)\n",
385
+ "\n",
386
+ " # Unpuck ZIPs Files\n",
387
+ " for directory in PREFIXES.values():\n",
388
+ " for root, _, files in os.walk(directory):\n",
389
+ " for file in files:\n",
390
+ " if file.endswith(\".zip\"):\n",
391
+ " zip_path = os.path.join(root, file)\n",
392
+ " extract_path = os.path.splitext(zip_path)[0]\n",
393
+ " with zipfile.ZipFile(zip_path, 'r') as zip_ref:\n",
394
+ " zip_ref.extractall(extract_path)\n",
395
+ " os.remove(zip_path)\n",
396
+ "\n",
397
+ "def handle_manual(url):\n",
398
+ " url_parts = url.split(':', 1)\n",
399
+ " prefix, path = url_parts[0], url_parts[1]\n",
400
+ "\n",
401
+ " file_name_match = re.search(r'\\[(.*?)\\]', path)\n",
402
+ " file_name = file_name_match.group(1) if file_name_match else None\n",
403
+ " if file_name:\n",
404
+ " path = re.sub(r'\\[.*?\\]', '', path)\n",
405
+ "\n",
406
+ " if prefix in PREFIXES:\n",
407
+ " dir = PREFIXES[prefix]\n",
408
+ " if prefix != \"extension\":\n",
409
+ " try:\n",
410
+ " manual_download(path, dir, file_name=file_name, prefix=prefix)\n",
411
+ " except Exception as e:\n",
412
+ " print(f\"Error downloading file: {e}\")\n",
413
+ " else:\n",
414
+ " extension_repo.append((path, file_name))\n",
415
+ "\n",
416
+ "def manual_download(url, dst_dir, file_name, prefix=None):\n",
417
+ " hf_header = f\"--header='Authorization: Bearer {huggingface_token}'\" if huggingface_token else \"\"\n",
418
+ " aria2c_header = \"--header='User-Agent: Mozilla/5.0' --allow-overwrite=true\"\n",
419
+ " aria2_args = \"--optimize-concurrent-downloads --console-log-level=error --summary-interval=10 --stderr=true -c -x16 -s16 -k1M -j5\"\n",
420
+ "\n",
421
+ " clean_url = strip_(url)\n",
422
+ "\n",
423
+ " if 'civitai' in url:\n",
424
+ " url, clean_url, model_type, file_name, image_url, image_name, data = CivitAi_API(url, file_name)\n",
425
+ " if image_url and image_name:\n",
426
+ " command = [\"aria2c\"] + aria2_args.split() + [\"-d\", dst_dir, \"-o\", image_name, image_url]\n",
427
+ " subprocess.run(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n",
428
+ "\n",
429
+ " elif 'github' in url or 'huggingface.co' in url:\n",
430
+ " if file_name and '.' not in file_name:\n",
431
+ " file_extension = f\"{clean_url.split('/')[-1].split('.', 1)[1]}\"\n",
432
+ " file_name = f\"{file_name}.{file_extension}\"\n",
433
+ " if not file_name:\n",
434
+ " file_name = clean_url.split(\"/\")[-1]\n",
435
+ "\n",
436
+ " \"\"\" Formatted info output \"\"\"\n",
437
+ " try:\n",
438
+ " format_output(clean_url, dst_dir, file_name, image_name, image_url)\n",
439
+ " except UnboundLocalError:\n",
440
+ " format_output(clean_url, dst_dir, file_name, None, None)\n",
441
+ "\n",
442
+ " # =====================\n",
443
+ " def run_aria2c(url, dst_dir, file_name=None, args=\"\", header=\"\"):\n",
444
+ " file_path = os.path.join(dst_dir, file_name) # replaces config files\n",
445
+ " if os.path.exists(file_path) and prefix == 'config':\n",
446
+ " os.remove(file_path)\n",
447
+ "\n",
448
+ " out = f\"-o '{file_name}'\" if file_name else \"\"\n",
449
+ " !aria2c {header} {args} -d {dst_dir} {out} '{url}'\n",
450
+ "\n",
451
+ " # -- Google Drive --\n",
452
+ " if 'drive.google' in url:\n",
453
+ " if not globals().get('have_drive_link', False):\n",
454
+ " os.system(\"pip install -U gdown > /dev/null\")\n",
455
+ " globals()['have_drive_link'] = True\n",
456
+ "\n",
457
+ " if 'folders' in url:\n",
458
+ " os.system(f\"gdown --folder \\\"{url}\\\" -O {dst_dir} --fuzzy -c\")\n",
459
+ " else:\n",
460
+ " out_path = f\"{dst_dir}/{file_name}\" if file_name else dst_dir\n",
461
+ " os.system(f\"gdown \\\"{url}\\\" -O {out_path} --fuzzy -c\")\n",
462
+ "\n",
463
+ " # -- GitHub or Hugging Face --\n",
464
+ " elif 'github' in url or 'huggingface' in url:\n",
465
+ " run_aria2c(clean_url, dst_dir, file_name, aria2_args, hf_header if 'huggingface' in url else '')\n",
466
+ "\n",
467
+ " # -- Other HTTP/Sources --\n",
468
+ " elif 'http' in url:\n",
469
+ " run_aria2c(url, dst_dir, file_name, aria2_args, aria2c_header)\n",
470
+ "\n",
471
+ "''' SubModels - Added URLs '''\n",
472
+ "\n",
473
+ "# Separation of merged numbers\n",
474
+ "def split_numbers(num_str, max_num):\n",
475
+ " result = []\n",
476
+ " i = 0\n",
477
+ " while i < len(num_str):\n",
478
+ " found = False\n",
479
+ " for length in range(2, 0, -1):\n",
480
+ " if i + length <= len(num_str):\n",
481
+ " part = int(num_str[i:i + length])\n",
482
+ " if part <= max_num:\n",
483
+ " result.append(part)\n",
484
+ " i += length\n",
485
+ " found = True\n",
486
+ " break\n",
487
+ " if not found:\n",
488
+ " break\n",
489
+ " return result\n",
490
+ "\n",
491
+ "def add_submodels(selection, num_selection, model_dict, dst_dir):\n",
492
+ " if selection == \"none\":\n",
493
+ " return []\n",
494
+ " selected_models = []\n",
495
+ "\n",
496
+ " if selection == \"ALL\":\n",
497
+ " selected_models = sum(model_dict.values(), [])\n",
498
+ " else:\n",
499
+ " if selection in model_dict:\n",
500
+ " selected_models.extend(model_dict[selection])\n",
501
+ "\n",
502
+ " nums = num_selection.replace(',', ' ').split()\n",
503
+ " max_num = len(model_dict)\n",
504
+ " unique_nums = set()\n",
505
+ "\n",
506
+ " for num_part in nums:\n",
507
+ " split_nums = split_numbers(num_part, max_num)\n",
508
+ " unique_nums.update(split_nums)\n",
509
+ "\n",
510
+ " for num in unique_nums:\n",
511
+ " if 1 <= num <= max_num:\n",
512
+ " name = list(model_dict.keys())[num - 1]\n",
513
+ " selected_models.extend(model_dict[name])\n",
514
+ "\n",
515
+ " unique_models = {model['name']: model for model in selected_models}.values()\n",
516
+ "\n",
517
+ " for model in unique_models:\n",
518
+ " model['dst_dir'] = dst_dir\n",
519
+ "\n",
520
+ " return list(unique_models)\n",
521
+ "\n",
522
+ "def handle_submodels(selection, num_selection, model_dict, dst_dir, url):\n",
523
+ " submodels = add_submodels(selection, num_selection, model_dict, dst_dir)\n",
524
+ " for submodel in submodels:\n",
525
+ " if not inpainting_model and \"inpainting\" in submodel['name']:\n",
526
+ " continue\n",
527
+ " url += f\"{submodel['url']} {submodel['dst_dir']} {submodel['name']}, \"\n",
528
+ " return url\n",
529
+ "\n",
530
+ "url = \"\"\n",
531
+ "url = handle_submodels(model, model_num, model_list, models_dir, url)\n",
532
+ "url = handle_submodels(vae, vae_num, vae_list, vaes_dir, url)\n",
533
+ "url = handle_submodels(controlnet, controlnet_num, controlnet_list, control_dir, url)\n",
534
+ "\n",
535
+ "''' file.txt - added urls '''\n",
536
+ "\n",
537
+ "def process_file_download(file_url, PREFIXES, unique_urls):\n",
538
+ " files_urls = \"\"\n",
539
+ "\n",
540
+ " if file_url.startswith(\"http\"):\n",
541
+ " if \"blob\" in file_url:\n",
542
+ " file_url = file_url.replace(\"blob\", \"raw\")\n",
543
+ " response = requests.get(file_url)\n",
544
+ " lines = response.text.split('\\n')\n",
545
+ " else:\n",
546
+ " with open(file_url, 'r') as file:\n",
547
+ " lines = file.readlines()\n",
548
+ "\n",
549
+ " current_tag = None\n",
550
+ " for line in lines:\n",
551
+ " line = line.strip()\n",
552
+ " if any(f'# {tag}' in line.lower() for tag in PREFIXES):\n",
553
+ " current_tag = next((tag for tag in PREFIXES if tag in line.lower()))\n",
554
+ "\n",
555
+ " urls = [url.split('#')[0].strip() for url in line.split(',')] # filter urls\n",
556
+ " for url in urls:\n",
557
+ " filter_url = url.split('[')[0] # same url filter\n",
558
+ "\n",
559
+ " if url.startswith(\"http\") and filter_url not in unique_urls:\n",
560
+ " files_urls += f\"{current_tag}:{url}, \"\n",
561
+ " unique_urls.add(filter_url)\n",
562
+ "\n",
563
+ " return files_urls\n",
564
+ "\n",
565
+ "file_urls = \"\"\n",
566
+ "unique_urls = set()\n",
567
+ "\n",
568
+ "if custom_file_urls:\n",
569
+ " for custom_file_url in custom_file_urls.replace(',', '').split():\n",
570
+ " if not custom_file_url.endswith('.txt'):\n",
571
+ " custom_file_url += '.txt'\n",
572
+ " if not custom_file_url.startswith('http'):\n",
573
+ " if not custom_file_url.startswith(root_path):\n",
574
+ " custom_file_url = f'{root_path}/{custom_file_url}'\n",
575
+ "\n",
576
+ " try:\n",
577
+ " file_urls += process_file_download(custom_file_url, PREFIXES, unique_urls)\n",
578
+ " except FileNotFoundError:\n",
579
+ " pass\n",
580
+ "\n",
581
+ "# url prefixing\n",
582
+ "urls = (Model_url, Vae_url, LoRA_url, Embedding_url, Extensions_url)\n",
583
+ "prefixed_urls = (f\"{prefix}:{url}\" for prefix, url in zip(PREFIXES.keys(), urls) if url for url in url.replace(',', '').split())\n",
584
+ "url += \", \".join(prefixed_urls) + \", \" + file_urls\n",
585
+ "\n",
586
+ "if detailed_download == \"on\":\n",
587
+ " print(\"\\n\\n\\033[33m# ====== Detailed Download ====== #\\n\\033[0m\")\n",
588
+ " download(url)\n",
589
+ " print(\"\\n\\033[33m# =============================== #\\n\\033[0m\")\n",
590
+ "else:\n",
591
+ " with capture.capture_output():\n",
592
+ " download(url)\n",
593
+ "\n",
594
+ "print(\"\\r🏁 Download Complete!\" + \" \"*15)\n",
595
+ "\n",
596
+ "\n",
597
+ "# Cleaning shit after downloading...\n",
598
+ "!find {webui_path} \\( -type d \\( -name \".ipynb_checkpoints\" -o -name \".aria2\" \\) -o -type f -name \"*.aria2\" \\) -exec rm -r {{}} \\; >/dev/null 2>&1\n",
599
+ "\n",
600
+ "\n",
601
+ "## Install of Custom extensions\n",
602
+ "if len(extension_repo) > 0:\n",
603
+ " print(\"✨ Installing custom extensions...\", end='')\n",
604
+ " with capture.capture_output():\n",
605
+ " for repo, repo_name in extension_repo:\n",
606
+ " if not repo_name:\n",
607
+ " repo_name = repo.split('/')[-1]\n",
608
+ " !cd {extensions_dir} \\\n",
609
+ " && git clone {repo} {repo_name} \\\n",
610
+ " && cd {repo_name} \\\n",
611
+ " && git fetch\n",
612
+ " print(f\"\\r📦 Installed '{len(extension_repo)}', Custom extensions!\")\n",
613
+ "\n",
614
+ "\n",
615
+ "## List Models and stuff V2\n",
616
+ "if detailed_download == \"off\":\n",
617
+ " print(\"\\n\\n\\033[33mIf you don't see any downloaded files, enable the 'Detailed Downloads' feature in the widget.\")\n",
618
+ "\n",
619
+ "%run {root_path}/file_cell/special/dl_display_results.py # display widgets result"
620
+ ]
621
+ }
622
+ ],
623
+ "metadata": {
624
+ "colab": {
625
+ "provenance": []
626
+ },
627
+ "kernelspec": {
628
+ "display_name": "Python 3",
629
+ "name": "python3"
630
+ },
631
+ "language_info": {
632
+ "name": "python"
633
+ }
634
+ },
635
+ "nbformat": 4,
636
+ "nbformat_minor": 0
637
+ }
files_cells/notebooks/en/launch_en.ipynb ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "nbformat": 4,
3
+ "nbformat_minor": 0,
4
+ "metadata": {
5
+ "colab": {
6
+ "provenance": []
7
+ },
8
+ "kernelspec": {
9
+ "name": "python3",
10
+ "display_name": "Python 3"
11
+ },
12
+ "language_info": {
13
+ "name": "python"
14
+ }
15
+ },
16
+ "cells": [
17
+ {
18
+ "cell_type": "code",
19
+ "execution_count": null,
20
+ "metadata": {
21
+ "id": "JKTCrY9LU7Oq"
22
+ },
23
+ "outputs": [],
24
+ "source": [
25
+ "##~ LAUNCH CODE | BY: ANXETY ~##\n",
26
+ "\n",
27
+ "import os\n",
28
+ "import re\n",
29
+ "import time\n",
30
+ "import json\n",
31
+ "import requests\n",
32
+ "import subprocess\n",
33
+ "import cloudpickle as pickle\n",
34
+ "from datetime import timedelta\n",
35
+ "from IPython.display import clear_output\n",
36
+ "\n",
37
+ "\n",
38
+ "# Setup Env\n",
39
+ "env = os.getenv('ENV_NAME')\n",
40
+ "root_path = os.getenv('ROOT_PATH')\n",
41
+ "webui_path = os.getenv('WEBUI_PATH')\n",
42
+ "free_plan = os.getenv('FREE_PLAN')\n",
43
+ "\n",
44
+ "\n",
45
+ "def load_settings():\n",
46
+ " SETTINGS_FILE = f'{root_path}/settings.json'\n",
47
+ " if os.path.exists(SETTINGS_FILE):\n",
48
+ " with open(SETTINGS_FILE, 'r') as f:\n",
49
+ " return json.load(f)\n",
50
+ " return {}\n",
51
+ "\n",
52
+ "settings = load_settings()\n",
53
+ "ngrok_token = settings.get('ngrok_token', \"\")\n",
54
+ "zrok_token = settings.get('zrok_token', \"\")\n",
55
+ "commandline_arguments = settings.get('commandline_arguments', \"\")\n",
56
+ "change_webui = settings.get('change_webui', \"\")\n",
57
+ "\n",
58
+ "\n",
59
+ "# ========================== OTHER ==========================\n",
60
+ "def is_package_installed(package_name):\n",
61
+ " try:\n",
62
+ " subprocess.run([\"npm\", \"ls\", \"-g\", package_name], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n",
63
+ " return True\n",
64
+ " except subprocess.CalledProcessError:\n",
65
+ " return False\n",
66
+ "\n",
67
+ "lt_tunnel = is_package_installed('localtunnel')\n",
68
+ "\n",
69
+ "\n",
70
+ "# ======================== TUNNEL V2 ========================\n",
71
+ "print('Please Wait...')\n",
72
+ "\n",
73
+ "def get_public_ip(version='ipv4'):\n",
74
+ " try:\n",
75
+ " url = f'https://api64.ipify.org?format=json&{version}=true'\n",
76
+ " response = requests.get(url)\n",
77
+ " return response.json().get('ip', 'N/A')\n",
78
+ " except Exception as e:\n",
79
+ " print(f\"Error getting public {version} address:\", e)\n",
80
+ "\n",
81
+ "# Check if public IP is already saved, if not then get it\n",
82
+ "public_ip_file = f\"{root_path}/public_ip.txt\"\n",
83
+ "if os.path.exists(public_ip_file):\n",
84
+ " with open(public_ip_file, 'r') as file:\n",
85
+ " public_ipv4 = file.read().strip()\n",
86
+ "else:\n",
87
+ " public_ipv4 = get_public_ip(version='ipv4')\n",
88
+ " with open(public_ip_file, 'w') as file:\n",
89
+ " file.write(public_ipv4)\n",
90
+ "\n",
91
+ "tunnel_class = pickle.load(open(f\"{root_path}/new_tunnel\", \"rb\"), encoding=\"utf-8\")\n",
92
+ "tunnel_port = 1834\n",
93
+ "tunnel = tunnel_class(tunnel_port)\n",
94
+ "tunnel.add_tunnel(command=\"cl tunnel --url localhost:{port}\", name=\"cl\", pattern=re.compile(r\"[\\w-]+\\.trycloudflare\\.com\"))\n",
95
+ "\n",
96
+ "if lt_tunnel:\n",
97
+ " tunnel.add_tunnel(command=\"lt --port {port}\", name=\"lt\", pattern=re.compile(r\"[\\w-]+\\.loca\\.lt\"), note=\"Password : \" + \"\\033[32m\" + public_ipv4 + \"\\033[0m\" + \" rerun cell if 404 error.\")\n",
98
+ "\n",
99
+ "if zrok_token:\n",
100
+ " !zrok enable {zrok_token} &> /dev/null\n",
101
+ " tunnel.add_tunnel(command=\"zrok share public http://localhost:{port}/ --headless\", name=\"zrok\", pattern=re.compile(r\"[\\w-]+\\.share\\.zrok\\.io\"))\n",
102
+ "\n",
103
+ "clear_output()\n",
104
+ "\n",
105
+ "\n",
106
+ "# ================= Automatic Fixing Path V3 ================\n",
107
+ "paths_to_check = {\n",
108
+ " \"tagger_hf_cache_dir\": f\"{webui_path}/models/interrogators/\",\n",
109
+ " \"ad_extra_models_dir\": f\"{webui_path}/models/adetailer/\",\n",
110
+ " \"sd_checkpoint_hash\": \"\",\n",
111
+ " \"sd_model_checkpoint\": \"\",\n",
112
+ " \"sd_vae\": \"None\"\n",
113
+ "}\n",
114
+ "\n",
115
+ "config_path = f'{webui_path}/config.json'\n",
116
+ "\n",
117
+ "if os.path.exists(config_path):\n",
118
+ " with open(config_path, 'r') as file:\n",
119
+ " config_data = json.load(file)\n",
120
+ "\n",
121
+ " for key, value in paths_to_check.items():\n",
122
+ " if key in config_data and config_data[key] != value:\n",
123
+ " sed_command = f\"sed -i 's|\\\"{key}\\\": \\\".*\\\"|\\\"{key}\\\": \\\"{value}\\\"|' {config_path}\"\n",
124
+ " os.system(sed_command)\n",
125
+ "\n",
126
+ "\n",
127
+ "with tunnel:\n",
128
+ " %cd {webui_path}\n",
129
+ "\n",
130
+ " commandline_arguments += f' --port={tunnel_port}'\n",
131
+ " if ngrok_token:\n",
132
+ " commandline_arguments += f' --ngrok {ngrok_token}'\n",
133
+ " if env != \"Google Colab\":\n",
134
+ " commandline_arguments += f' --encrypt-pass={tunnel_port} --api'\n",
135
+ "\n",
136
+ " if change_webui == 'A1111':\n",
137
+ " commandline_arguments += ' --xformers'\n",
138
+ " else:\n",
139
+ " commandline_arguments += ' --disable-xformers --opt-sdp-attention --cuda-stream --pin-shared-memory'\n",
140
+ "\n",
141
+ " !COMMANDLINE_ARGS=\"{commandline_arguments}\" python launch.py\n",
142
+ "\n",
143
+ "start_colab = float(open(f'{webui_path}/static/colabTimer.txt', 'r').read())\n",
144
+ "time_since_start = str(timedelta(seconds=time.time()-start_colab)).split('.')[0]\n",
145
+ "print(f\"\\n⌚️ \\033[0mYou have been conducting this session for - \\033[33m{time_since_start}\\033[0m\\n\\n\")\n",
146
+ "\n",
147
+ "if zrok_token:\n",
148
+ " !zrok disable &> /dev/null"
149
+ ]
150
+ }
151
+ ]
152
+ }
files_cells/notebooks/en/widgets_en.ipynb ADDED
@@ -0,0 +1,354 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "nbformat": 4,
3
+ "nbformat_minor": 0,
4
+ "metadata": {
5
+ "colab": {
6
+ "provenance": []
7
+ },
8
+ "kernelspec": {
9
+ "name": "python3",
10
+ "display_name": "Python 3"
11
+ },
12
+ "language_info": {
13
+ "name": "python"
14
+ }
15
+ },
16
+ "cells": [
17
+ {
18
+ "cell_type": "code",
19
+ "execution_count": null,
20
+ "metadata": {
21
+ "id": "JKTCrY9LU7Oq"
22
+ },
23
+ "outputs": [],
24
+ "source": [
25
+ "##~ WIDGET CODE | BY: ANXETY ~##\n",
26
+ "\n",
27
+ "import os\n",
28
+ "import json\n",
29
+ "import time\n",
30
+ "from ipywidgets import widgets\n",
31
+ "from IPython.display import display, HTML, Javascript, clear_output\n",
32
+ "\n",
33
+ "\n",
34
+ "# Setup Env\n",
35
+ "env = os.getenv('ENV_NAME')\n",
36
+ "root_path = os.getenv('ROOT_PATH')\n",
37
+ "webui_path = os.getenv('WEBUI_PATH')\n",
38
+ "free_plan = os.getenv('FREE_PLAN')\n",
39
+ "\n",
40
+ "\n",
41
+ "# ==================== CSS JS ====================\n",
42
+ "##~ custom background images V1.5 ~##\n",
43
+ "import argparse\n",
44
+ "parser = argparse.ArgumentParser(description='This script processes an background image.')\n",
45
+ "parser.add_argument('-i', '--image', type=str, help='URL of the image to process', metavar='')\n",
46
+ "parser.add_argument('-o', '--opacity', type=float, help='Opacity level for the image, between 0 and 1', metavar='', default=0.3)\n",
47
+ "parser.add_argument('-b', '--blur', type=str, help='Blur level for the image', metavar='', default=0)\n",
48
+ "parser.add_argument('-y', type=int, help='Y coordinate for the image in px', metavar='', default=0)\n",
49
+ "parser.add_argument('-x', type=int, help='X coordinate for the image in px', metavar='', default=0)\n",
50
+ "parser.add_argument('-s', '--scale', type=int, help='Scale image in %%', metavar='', default=100)\n",
51
+ "parser.add_argument('-m', '--mode', action='store_true', help='Removes repetitive image tiles')\n",
52
+ "parser.add_argument('-t', '--transparent', action='store_true', help='Makes input/selection fields 35%% more transparent')\n",
53
+ "parser.add_argument('-bf', '--blur-fields', type=str, help='Background blur level for input/selection fields', metavar='', default=2)\n",
54
+ "\n",
55
+ "args = parser.parse_args()\n",
56
+ "\n",
57
+ "url_img = args.image\n",
58
+ "opacity_img = args.opacity\n",
59
+ "blur_img = args.blur\n",
60
+ "y_img = args.y\n",
61
+ "x_img = args.x\n",
62
+ "scale_img = args.scale\n",
63
+ "blur_fields = args.blur_fields\n",
64
+ "\n",
65
+ "## ---\n",
66
+ "\"\"\" WTF KAGGLE - WHAT THE FUCK IS THE DIFFERENCE OF 35 PIXELS!?!?!? \"\"\"\n",
67
+ "fix_heigh_img = \"-810px\" if env == \"Kaggle\" else \"-775px\"\n",
68
+ "\n",
69
+ "\"\"\" transperent fields \"\"\"\n",
70
+ "t_bg_alpha = \"1\" if not args.transparent else \"0.65\"\n",
71
+ "\n",
72
+ "\"\"\" mode img - repeats \"\"\"\n",
73
+ "mode_img = \"repeat\" if not args.mode else \"no-repeat\"\n",
74
+ "\n",
75
+ "container_background = f'''\n",
76
+ "<style>\n",
77
+ ":root {{\n",
78
+ " /* for background container*/\n",
79
+ " --img_background: url({url_img});\n",
80
+ " --img_opacity: {opacity_img};\n",
81
+ " --img_blur: {blur_img}px;\n",
82
+ " --image_y: {y_img}px;\n",
83
+ " --image_x: {x_img}px;\n",
84
+ " --img_scale: {scale_img}%;\n",
85
+ " --img_mode: {mode_img};\n",
86
+ " --img_height_dif: {fix_heigh_img};\n",
87
+ "\n",
88
+ " /* for fields */\n",
89
+ " --bg-field-color: rgba(28, 28, 28, {t_bg_alpha}); /* -> #1c1c1c */\n",
90
+ " --bg-field-color-hover: rgba(38, 38, 38, {t_bg_alpha}); /* -> #262626; */\n",
91
+ " --bg-field-blur-level: {blur_fields}px;\n",
92
+ "}}\n",
93
+ "'''\n",
94
+ "\n",
95
+ "display(HTML(container_background))\n",
96
+ "\n",
97
+ "# Main CSS\n",
98
+ "css_file_path = f\"{root_path}/CSS/main_widgets.css\"\n",
99
+ "with open(css_file_path , \"r\") as f:\n",
100
+ " CSS = f.read()\n",
101
+ "display(HTML(f\"<style>{CSS}</style>\"))\n",
102
+ "\n",
103
+ "# Main JS\n",
104
+ "JS = '''\n",
105
+ "<!-- TOGGLE 'CustomDL' SCRIPT -->\n",
106
+ "<script>\n",
107
+ "function toggleContainer() {\n",
108
+ " let downloadContainer = document.querySelector('.container_custom_downlad');\n",
109
+ " let info = document.querySelector('.info');\n",
110
+ "\n",
111
+ " downloadContainer.classList.toggle('expanded');\n",
112
+ " info.classList.toggle('showed');\n",
113
+ "}\n",
114
+ "</script>\n",
115
+ "'''\n",
116
+ "display(HTML(JS))\n",
117
+ "\n",
118
+ "\n",
119
+ "# ==================== WIDGETS V2 ====================\n",
120
+ "HR = widgets.HTML('<hr>')\n",
121
+ "\n",
122
+ "class WidgetFactory:\n",
123
+ " def __init__(self, style=None, layout=None):\n",
124
+ " self.style = style if style else {'description_width': 'initial'}\n",
125
+ " self.layout = layout if layout else widgets.Layout(max_width='1080px', width='100%')\n",
126
+ "\n",
127
+ " def create_html(self, content, class_name=None):\n",
128
+ " html_widget = widgets.HTML(content)\n",
129
+ " if class_name:\n",
130
+ " html_widget.add_class(class_name)\n",
131
+ " return html_widget\n",
132
+ "\n",
133
+ " def create_header(self, name):\n",
134
+ " return widgets.HTML(f'<div class=\"header\">{name}<div>')\n",
135
+ "\n",
136
+ " def create_dropdown(self, options, value, description):\n",
137
+ " return widgets.Dropdown(options=options, value=value, description=description, style=self.style, layout=self.layout)\n",
138
+ "\n",
139
+ " def create_text(self, description, placeholder='', value=''):\n",
140
+ " return widgets.Text(description=description, placeholder=placeholder, value=value, style=self.style, layout=self.layout)\n",
141
+ "\n",
142
+ " def create_checkbox(self, value, description):\n",
143
+ " return widgets.Checkbox(value=value, description=description, style=self.style, layout=self.layout)\n",
144
+ "\n",
145
+ " def create_button(self, description, class_name=None):\n",
146
+ " button = widgets.Button(description=description)\n",
147
+ " if class_name:\n",
148
+ " button.add_class(class_name)\n",
149
+ " return button\n",
150
+ "\n",
151
+ " def create_hbox(self, children):\n",
152
+ " return widgets.HBox(children)\n",
153
+ "\n",
154
+ " def create_vbox(self, children, class_names=None):\n",
155
+ " vbox = widgets.VBox(children)\n",
156
+ " if class_names:\n",
157
+ " for class_name in class_names:\n",
158
+ " vbox.add_class(class_name)\n",
159
+ " return vbox\n",
160
+ "\n",
161
+ " def display(self, widget):\n",
162
+ " display(widget)\n",
163
+ "\n",
164
+ "# Instantiate the factory\n",
165
+ "factory = WidgetFactory()\n",
166
+ "\n",
167
+ "# --- MODEL ---\n",
168
+ "model_header = factory.create_header('Model Selection')\n",
169
+ "model_options = ['none',\n",
170
+ " '1.Anime (by XpucT) + INP',\n",
171
+ " '2.BluMix [Anime] [V7] + INP',\n",
172
+ " '3.Cetus-Mix [Anime] [V4] + INP',\n",
173
+ " '4.Counterfeit [Anime] [V3] + INP',\n",
174
+ " '5.CuteColor [Anime] [V3]',\n",
175
+ " '6.Dark-Sushi-Mix [Anime]',\n",
176
+ " '7.Deliberate [Realism] [V6] + INP',\n",
177
+ " '8.Meina-Mix [Anime] [V11] + INP',\n",
178
+ " '9.Mix-Pro [Anime] [V4] + INP']\n",
179
+ "model_widget = factory.create_dropdown(model_options, '4.Counterfeit [Anime] [V3] + INP', 'Model:')\n",
180
+ "model_num_widget = factory.create_text('Model Number:', 'Enter the model numbers to be downloaded using comma/space.')\n",
181
+ "inpainting_model_widget = factory.create_checkbox(False, 'Inpainting Models')\n",
182
+ "\n",
183
+ "# Display Model\n",
184
+ "all_model_box = factory.create_vbox([model_header, model_widget, model_num_widget, inpainting_model_widget], class_names=[\"container\", \"image_1\"])\n",
185
+ "factory.display(all_model_box)\n",
186
+ "\n",
187
+ "# --- VAE ---\n",
188
+ "vae_header = factory.create_header('VAE Selection')\n",
189
+ "vae_options = ['none',\n",
190
+ " '1.Anime.vae',\n",
191
+ " '2.Anything.vae',\n",
192
+ " '3.Blessed2.vae',\n",
193
+ " '4.ClearVae.vae',\n",
194
+ " '5.WD.vae']\n",
195
+ "vae_widget = factory.create_dropdown(vae_options, '3.Blessed2.vae', 'Vae:')\n",
196
+ "vae_num_widget = factory.create_text('Vae Number:', 'Enter the vae numbers to be downloaded using comma/space.')\n",
197
+ "\n",
198
+ "# Display Vae\n",
199
+ "all_vae_box = factory.create_vbox([vae_header, vae_widget, vae_num_widget], class_names=[\"container\", \"image_2\"])\n",
200
+ "factory.display(all_vae_box)\n",
201
+ "\n",
202
+ "# --- ADDITIONAL ---\n",
203
+ "additional_header = factory.create_header('Additional')\n",
204
+ "latest_webui_widget = factory.create_checkbox(True, 'Update WebUI')\n",
205
+ "latest_exstensions_widget = factory.create_checkbox(True, 'Update Extensions')\n",
206
+ "change_webui_widget = factory.create_dropdown(['A1111', 'Forge'], 'A1111', 'Change WebUI:')\n",
207
+ "detailed_download_widget = factory.create_dropdown(['off', 'on'], 'off', 'Detailed Download:')\n",
208
+ "choose_changes_widget = factory.create_hbox([latest_webui_widget, latest_exstensions_widget, change_webui_widget, detailed_download_widget])\n",
209
+ "\n",
210
+ "controlnet_options = ['none', 'ALL', '1.canny',\n",
211
+ " '2.openpose', '3.depth',\n",
212
+ " '4.normal_map', '5.mlsd',\n",
213
+ " '6.lineart', '7.soft_edge',\n",
214
+ " '8.scribble', '9.segmentation',\n",
215
+ " '10.shuffle', '11.tile',\n",
216
+ " '12.inpaint', '13.instruct_p2p']\n",
217
+ "controlnet_widget = factory.create_dropdown(controlnet_options, 'none', 'ControlNet:')\n",
218
+ "controlnet_num_widget = factory.create_text('ControlNet Number:', 'Enter the ControlNet model numbers to be downloaded using comma/space.')\n",
219
+ "commit_hash_widget = factory.create_text('Commit Hash:')\n",
220
+ "huggingface_token_widget = factory.create_text('HuggingFace Token:')\n",
221
+ "\n",
222
+ "ngrok_token_widget = factory.create_text('Ngrok Token:')\n",
223
+ "ngrock_button = factory.create_html('<a href=\"https://dashboard.ngrok.com/get-started/your-authtoken\" target=\"_blank\">Получить Ngrok Токен</a>', class_name=\"button_ngrok\")\n",
224
+ "ngrok_widget = factory.create_hbox([ngrok_token_widget, ngrock_button])\n",
225
+ "\n",
226
+ "zrok_token_widget = factory.create_text('Zrok Token:')\n",
227
+ "zrok_button = factory.create_html('<a href=\"https://colab.research.google.com/drive/1d2sjWDJi_GYBUavrHSuQyHTDuLy36WpU\" target=\"_blank\">Зарегать Zrok Токен</a>', class_name=\"button_ngrok\")\n",
228
+ "zrok_widget = factory.create_hbox([zrok_token_widget, zrok_button])\n",
229
+ "\n",
230
+ "commandline_arguments_options = \"--listen --enable-insecure-extension-access --theme dark --no-half-vae --disable-console-progressbars\"\n",
231
+ "commandline_arguments_widget = factory.create_text('Arguments:', value=commandline_arguments_options)\n",
232
+ "\n",
233
+ "# Display Additional\n",
234
+ "additional_widget_list = [additional_header,\n",
235
+ " choose_changes_widget,\n",
236
+ " HR,\n",
237
+ " controlnet_widget,\n",
238
+ " controlnet_num_widget,\n",
239
+ " commit_hash_widget,\n",
240
+ " huggingface_token_widget,\n",
241
+ " ngrok_widget,\n",
242
+ " zrok_widget,\n",
243
+ " HR,\n",
244
+ " commandline_arguments_widget]\n",
245
+ "\n",
246
+ "if free_plan and env == \"Google Colab\": # remove ngrok from colab\n",
247
+ " additional_widget_list.remove(ngrok_widget)\n",
248
+ "\n",
249
+ "all_additional_box = factory.create_vbox(additional_widget_list, class_names=[\"container\", \"image_3\"])\n",
250
+ "factory.display(all_additional_box)\n",
251
+ "\n",
252
+ "# --- CUSTOM DOWNLOAD ---\n",
253
+ "custom_download_header_popup = factory.create_html('''\n",
254
+ "<style>\n",
255
+ "/* Term Colors */\n",
256
+ ".sample_label {color: #dbafff;}\n",
257
+ ".braces {color: #ffff00;}\n",
258
+ ".extension {color: #eb934b;}\n",
259
+ ".file_name {color: #ffffd8;}\n",
260
+ "</style>\n",
261
+ "\n",
262
+ "<div class=\"header\" style=\"cursor: pointer;\" onclick=\"toggleContainer()\">Custom Download</div>\n",
263
+ "<!-- PopUp Window -->\n",
264
+ "<div class=\"info\">INFO</div>\n",
265
+ "<div class=\"popup\">\n",
266
+ " Separate multiple URLs with a comma/space. For a <span class=\"file_name\">custom name</span> file/extension, specify it with <span class=\"braces\">[]</span>\n",
267
+ " after the URL without spaces.\n",
268
+ " <span style=\"color: #ff9999\">For files, be sure to specify</span> - <span class=\"extension\">Filename Extension.</span>\n",
269
+ " <div class=\"sample\">\n",
270
+ " <span class=\"sample_label\">Example for File:</span>\n",
271
+ " https://civitai.com/api/download/models/229782<span class=\"braces\">[</span><span class=\"file_name\">Detailer</span><span class=\"extension\">.safetensors</span><span class=\"braces\">]</span>\n",
272
+ " <br>\n",
273
+ " <span class=\"sample_label\">Example for Extension:</span>\n",
274
+ " https://github.com/hako-mikan/sd-webui-regional-prompter<span class=\"braces\">[</span><span class=\"file_name\">Regional-Prompter</span><span class=\"braces\">]</span>\n",
275
+ " </div>\n",
276
+ "</div>\n",
277
+ "''')\n",
278
+ "\n",
279
+ "Model_url_widget = factory.create_text('Model:')\n",
280
+ "Vae_url_widget = factory.create_text('Vae:')\n",
281
+ "LoRA_url_widget = factory.create_text('LoRa:')\n",
282
+ "Embedding_url_widget = factory.create_text('Embedding:')\n",
283
+ "Extensions_url_widget = factory.create_text('Extensions:')\n",
284
+ "custom_file_urls_widget = factory.create_text('File (txt):')\n",
285
+ "\n",
286
+ "# Display CustomDl\n",
287
+ "all_custom_box = factory.create_vbox([\n",
288
+ " custom_download_header_popup, Model_url_widget, Vae_url_widget, LoRA_url_widget, Embedding_url_widget, Extensions_url_widget, custom_file_urls_widget\n",
289
+ "], class_names=[\"container\", \"image_4\", \"container_custom_downlad\"])\n",
290
+ "factory.display(all_custom_box)\n",
291
+ "\n",
292
+ "# --- Save Button ---\n",
293
+ "save_button = factory.create_button('Save', class_name=\"button_save\")\n",
294
+ "factory.display(save_button)\n",
295
+ "\n",
296
+ "\n",
297
+ "# ==================== OTHER FUNC ====================\n",
298
+ "# Setup UI\n",
299
+ "def setup_webui(change_webui_widget):\n",
300
+ " if 'SDW_UI' in os.environ:\n",
301
+ " UI = os.environ['SDW_UI']\n",
302
+ " else:\n",
303
+ " os.environ['SDW_UI'] = change_webui_widget\n",
304
+ " os.environ['SDW_OLD_UI'] = change_webui_widget\n",
305
+ "\n",
306
+ " UI = os.getenv('SDW_UI')\n",
307
+ "\n",
308
+ " if UI != change_webui_widget:\n",
309
+ " os.environ['SDW_UI'] = change_webui_widget\n",
310
+ "\n",
311
+ "\n",
312
+ "# ============ Load / Save - Settings V2 ============\n",
313
+ "SETTINGS_FILE = f'{root_path}/settings.json'\n",
314
+ "\n",
315
+ "SETTINGS_KEYS = [\n",
316
+ " 'model', 'model_num', 'inpainting_model',\n",
317
+ " 'vae', 'vae_num', 'latest_webui', 'latest_exstensions',\n",
318
+ " 'change_webui', 'detailed_download', 'controlnet',\n",
319
+ " 'controlnet_num', 'commit_hash', 'huggingface_token',\n",
320
+ " 'ngrok_token', 'zrok_token', 'commandline_arguments',\n",
321
+ " 'Model_url', 'Vae_url', 'LoRA_url', 'Embedding_url',\n",
322
+ " 'Extensions_url', 'custom_file_urls'\n",
323
+ "]\n",
324
+ "\n",
325
+ "def save_settings():\n",
326
+ " settings = {key: globals()[f\"{key}_widget\"].value for key in SETTINGS_KEYS}\n",
327
+ " with open(SETTINGS_FILE, 'w') as f:\n",
328
+ " json.dump(settings, f, indent=2)\n",
329
+ "\n",
330
+ "def load_settings():\n",
331
+ " if os.path.exists(SETTINGS_FILE):\n",
332
+ " with open(SETTINGS_FILE, 'r') as f:\n",
333
+ " settings = json.load(f)\n",
334
+ " for key in SETTINGS_KEYS:\n",
335
+ " globals()[f\"{key}_widget\"].value = settings.get(key, \"\")\n",
336
+ "\n",
337
+ "def hide_widgets():\n",
338
+ " widgets_list = [all_model_box, all_vae_box, all_additional_box, all_custom_box, save_button]\n",
339
+ " for widget in widgets_list:\n",
340
+ " widget.add_class(\"hide\")\n",
341
+ " time.sleep(0.5)\n",
342
+ " widgets.Widget.close_all()\n",
343
+ "\n",
344
+ "def save_data(button):\n",
345
+ " save_settings()\n",
346
+ " setup_webui(change_webui_widget.value)\n",
347
+ " hide_widgets()\n",
348
+ "\n",
349
+ "load_settings()\n",
350
+ "save_button.on_click(save_data)"
351
+ ]
352
+ }
353
+ ]
354
+ }
files_cells/notebooks/ru/auto_cleaner_ru.ipynb ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "nbformat": 4,
3
+ "nbformat_minor": 0,
4
+ "metadata": {
5
+ "colab": {
6
+ "provenance": []
7
+ },
8
+ "kernelspec": {
9
+ "name": "python3",
10
+ "display_name": "Python 3"
11
+ },
12
+ "language_info": {
13
+ "name": "python"
14
+ }
15
+ },
16
+ "cells": [
17
+ {
18
+ "cell_type": "code",
19
+ "execution_count": null,
20
+ "metadata": {
21
+ "id": "JKTCrY9LU7Oq"
22
+ },
23
+ "outputs": [],
24
+ "source": [
25
+ "##~ AutoCleaner V3.7 CODE | BY: ANXETY ~##\n",
26
+ "\n",
27
+ "from directory_setup import models_dir, vaes_dir, control_dir, loras_dir, output_dir\n",
28
+ "\n",
29
+ "import os\n",
30
+ "import time\n",
31
+ "from ipywidgets import widgets\n",
32
+ "from IPython.display import display, HTML\n",
33
+ "\n",
34
+ "\n",
35
+ "# Setup Env\n",
36
+ "env = os.getenv('ENV_NAME')\n",
37
+ "root_path = os.getenv('ROOT_PATH')\n",
38
+ "webui_path = os.getenv('WEBUI_PATH')\n",
39
+ "free_plan = os.getenv('FREE_PLAN')\n",
40
+ "\n",
41
+ "\n",
42
+ "# ==================== CSS ====================\n",
43
+ "# Main CSS\n",
44
+ "css_file_path = f\"{root_path}/CSS/auto_cleaner.css\"\n",
45
+ "with open(css_file_path , \"r\") as f:\n",
46
+ " CSS_AC = f.read()\n",
47
+ "display(HTML(f\"<style>{CSS_AC}</style>\"))\n",
48
+ "\n",
49
+ "\n",
50
+ "# ================ AutoCleaner function ================\n",
51
+ "directories = {\n",
52
+ " \"Изображения\": output_dir,\n",
53
+ " \"Модели\": models_dir,\n",
54
+ " \"Vae\": vaes_dir,\n",
55
+ " \"LoRa\": loras_dir,\n",
56
+ " \"ControlNet Модели\": control_dir\n",
57
+ "}\n",
58
+ "\n",
59
+ "\"\"\" functions \"\"\"\n",
60
+ "def clean_directory(directory, directory_type):\n",
61
+ " deleted_files = 0\n",
62
+ "\n",
63
+ " for root, dirs, files in os.walk(directory):\n",
64
+ " for file in files:\n",
65
+ " file_path = os.path.join(root, file)\n",
66
+ "\n",
67
+ " if file.endswith(\".txt\"):\n",
68
+ " continue\n",
69
+ " if file.endswith((\".safetensors\", \".pt\")) or directory_type == \"Images\":\n",
70
+ " deleted_files += 1\n",
71
+ "\n",
72
+ " os.remove(file_path)\n",
73
+ " return deleted_files\n",
74
+ "\n",
75
+ "def update_memory_info():\n",
76
+ " disk_space = psutil.disk_usage(os.getcwd())\n",
77
+ " total = disk_space.total / (1024 ** 3)\n",
78
+ " used = disk_space.used / (1024 ** 3)\n",
79
+ " free = disk_space.free / (1024 ** 3)\n",
80
+ "\n",
81
+ " storage_info.value = f'''\n",
82
+ " <div class=\"storage_info_AC\">Всего: {total:.2f} GB <span style=\"color: #555\">|</span> Используется: {used:.2f} GB <span style=\"color: #555\">|</span> Свободно: {free:.2f} GB</div>\n",
83
+ " '''\n",
84
+ "\n",
85
+ "def on_execute_button_press(button):\n",
86
+ " selected_cleaners = auto_cleaner_widget.value\n",
87
+ " deleted_files_dict = {}\n",
88
+ "\n",
89
+ " for option in selected_cleaners:\n",
90
+ " if option in directories:\n",
91
+ " deleted_files_dict[option] = clean_directory(directories[option], option)\n",
92
+ "\n",
93
+ " output.clear_output()\n",
94
+ "\n",
95
+ " with output:\n",
96
+ " for message in generate_messages(deleted_files_dict):\n",
97
+ " message_widget = HTML(f'<p class=\"output_message_AC\">{message}</p>')\n",
98
+ " display(message_widget)\n",
99
+ "\n",
100
+ " update_memory_info()\n",
101
+ "\n",
102
+ "def on_clear_button_press(button):\n",
103
+ " container.add_class(\"hide\")\n",
104
+ " time.sleep(0.5)\n",
105
+ " widgets.Widget.close_all()\n",
106
+ "\n",
107
+ "def generate_messages(deleted_files_dict):\n",
108
+ " messages = []\n",
109
+ " word_variants = {\n",
110
+ " \"Изображения\": \"Изображений\",\n",
111
+ " \"Модели\": \"Моделей\",\n",
112
+ " \"Vae\": \"Vae\",\n",
113
+ " \"LoRa\": \"LoRa\",\n",
114
+ " \"ControlNet Модели\": \"ControlNet Моделей\"\n",
115
+ " }\n",
116
+ " for key, value in deleted_files_dict.items():\n",
117
+ " object_word = word_variants.get(key)\n",
118
+ " messages.append(f\"Удалено {value} {object_word}\")\n",
119
+ " return messages\n",
120
+ "\n",
121
+ "\n",
122
+ "# --- storage memory ---\n",
123
+ "import psutil\n",
124
+ "disk_space = psutil.disk_usage(os.getcwd())\n",
125
+ "total = disk_space.total / (1024 ** 3)\n",
126
+ "used = disk_space.used / (1024 ** 3)\n",
127
+ "free = disk_space.free / (1024 ** 3)\n",
128
+ "\n",
129
+ "\n",
130
+ "# ================ Widgets ================\n",
131
+ "# UI Code\n",
132
+ "AutoCleaner_options = AutoCleaner_options = list(directories.keys())\n",
133
+ "instruction_label = widgets.HTML('''\n",
134
+ "<span class=\"instruction_AC\">Используйте <span style=\"color: #B2B2B2;\">ctrl</span> или <span style=\"color: #B2B2B2;\">shift</span> для множественного выбора.</span>\n",
135
+ "''')\n",
136
+ "auto_cleaner_widget = widgets.SelectMultiple(options=AutoCleaner_options, layout=widgets.Layout(width=\"auto\")).add_class(\"custom-select-multiple_AC\")\n",
137
+ "output = widgets.Output().add_class(\"output_AC\")\n",
138
+ "\n",
139
+ "execute_button = widgets.Button(description='Выполнить Очистку').add_class(\"button_execute_AC\").add_class(\"button_AC\")\n",
140
+ "execute_button.on_click(on_execute_button_press)\n",
141
+ "clear_button = widgets.Button(description='Скрыть Виджет').add_class(\"button_clear_AC\").add_class(\"button_AC\")\n",
142
+ "clear_button.on_click(on_clear_button_press)\n",
143
+ "\n",
144
+ "storage_info = widgets.HTML(f'''\n",
145
+ "<div class=\"storage_info_AC\">Всего: {total:.2f} GB <span style=\"color: #555\">|</span> Используется: {used:.2f} GB <span style=\"color: #555\">|</span> Свободно: {free:.2f} GB</div>\n",
146
+ "''')\n",
147
+ "\n",
148
+ "buttons = widgets.HBox([execute_button, clear_button])\n",
149
+ "lower_information_panel = widgets.HBox([buttons, storage_info]).add_class(\"lower_information_panel_AC\")\n",
150
+ "\n",
151
+ "container = widgets.VBox([instruction_label, widgets.HTML('<hr>'), auto_cleaner_widget, output, widgets.HTML('<hr>'), lower_information_panel]).add_class(\"container_AC\")\n",
152
+ "\n",
153
+ "display(container)"
154
+ ]
155
+ }
156
+ ]
157
+ }
files_cells/notebooks/ru/downloading_ru.ipynb ADDED
@@ -0,0 +1,637 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "metadata": {
7
+ "id": "2lJmbqrs3Mu8"
8
+ },
9
+ "outputs": [],
10
+ "source": [
11
+ "##~ DOWNLOADING CODE | BY: ANXETY ~##\n",
12
+ "\n",
13
+ "from directory_setup import *\n",
14
+ "from models_data import model_list, vae_list, controlnet_list\n",
15
+ "\n",
16
+ "import os\n",
17
+ "import re\n",
18
+ "import time\n",
19
+ "import json\n",
20
+ "import shutil\n",
21
+ "import zipfile\n",
22
+ "import requests\n",
23
+ "import subprocess\n",
24
+ "from datetime import timedelta\n",
25
+ "from subprocess import getoutput\n",
26
+ "from IPython.utils import capture\n",
27
+ "from IPython.display import clear_output\n",
28
+ "from urllib.parse import urlparse, parse_qs\n",
29
+ "\n",
30
+ "\n",
31
+ "# Setup Env\n",
32
+ "env = os.getenv('ENV_NAME')\n",
33
+ "root_path = os.getenv('ROOT_PATH')\n",
34
+ "webui_path = os.getenv('WEBUI_PATH')\n",
35
+ "free_plan = os.getenv('FREE_PLAN')\n",
36
+ "\n",
37
+ "UI = os.getenv('SDW_UI')\n",
38
+ "OLD_UI = os.getenv('SDW_OLD_UI')\n",
39
+ "\n",
40
+ "os.chdir(root_path)\n",
41
+ "\n",
42
+ "\n",
43
+ "# ============ loading settings V4 =============\n",
44
+ "def load_settings(path):\n",
45
+ " if os.path.exists(path):\n",
46
+ " with open(path, 'r') as file:\n",
47
+ " return json.load(file)\n",
48
+ " return {}\n",
49
+ "\n",
50
+ "settings = load_settings(f'{root_path}/settings.json')\n",
51
+ "\n",
52
+ "VARIABLES = [\n",
53
+ " 'model', 'model_num', 'inpainting_model',\n",
54
+ " 'vae', 'vae_num', 'latest_webui', 'latest_exstensions',\n",
55
+ " 'change_webui', 'detailed_download', 'controlnet',\n",
56
+ " 'controlnet_num', 'commit_hash', 'huggingface_token',\n",
57
+ " 'ngrok_token', 'zrok_token', 'commandline_arguments',\n",
58
+ " 'Model_url', 'Vae_url', 'LoRA_url', 'Embedding_url',\n",
59
+ " 'Extensions_url', 'custom_file_urls'\n",
60
+ "]\n",
61
+ "\n",
62
+ "locals().update({key: settings.get(key) for key in VARIABLES})\n",
63
+ "\n",
64
+ "\n",
65
+ "# ================ LIBRARIES V2 ================\n",
66
+ "flag_file = f\"{root_path}/libraries_installed.txt\"\n",
67
+ "\n",
68
+ "if not os.path.exists(flag_file):\n",
69
+ " print(\"💿 Установка библиотек, это займет какое-то время:\\n\")\n",
70
+ "\n",
71
+ " install_lib = {\n",
72
+ " # \"aria2\": \"apt -y install aria2\",\n",
73
+ " \"aria2\": \"pip install aria2\",\n",
74
+ " \"localtunnel\": \"npm install -g localtunnel\",\n",
75
+ " }\n",
76
+ " if controlnet != 'none':\n",
77
+ " install_lib[\"insightface\"] = \"pip install insightface\"\n",
78
+ "\n",
79
+ " additional_libs = {\n",
80
+ " \"Google Colab\": {\n",
81
+ " \"xformers\": \"pip install xformers==0.0.27 --no-deps\"\n",
82
+ " },\n",
83
+ " \"Kaggle\": {\n",
84
+ " \"xformers\": \"pip install xformers==0.0.26.post1\",\n",
85
+ " # \"torch\": \"pip install torch==2.1.2+cu121 torchvision==0.16.2+cu121 torchaudio==2.1.2 --extra-index-url https://download.pytorch.org/whl/cu121\",\n",
86
+ " # \"aiohttp\": \"pip install trash-cli && trash-put /opt/conda/lib/python3.10/site-packages/aiohttp*\" # fix install req\n",
87
+ " }\n",
88
+ " }\n",
89
+ " if env in additional_libs:\n",
90
+ " install_lib.update(additional_libs[env])\n",
91
+ "\n",
92
+ " # Loop through libraries\n",
93
+ " for index, (package, install_cmd) in enumerate(install_lib.items(), start=1):\n",
94
+ " print(f\"\\r[{index}/{len(install_lib)}] \\033[32m>>\\033[0m Installing \\033[33m{package}\\033[0m...\" + \" \"*35, end='')\n",
95
+ " subprocess.run(install_cmd, shell=True, capture_output=True)\n",
96
+ "\n",
97
+ " # Additional specific packages\n",
98
+ " with capture.capture_output():\n",
99
+ " !curl -s -OL https://github.com/DEX-1101/sd-webui-notebook/raw/main/res/new_tunnel --output-dir {root_path}\n",
100
+ " !curl -s -Lo /usr/bin/cl https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 && chmod +x /usr/bin/cl\n",
101
+ " !curl -sLO https://github.com/openziti/zrok/releases/download/v0.4.32/zrok_0.4.32_linux_amd64.tar.gz && tar -xzf zrok_0.4.32_linux_amd64.tar.gz -C /usr/bin && rm -f zrok_0.4.32_linux_amd64.tar.gz\n",
102
+ "\n",
103
+ " clear_output()\n",
104
+ "\n",
105
+ " # Save file install lib\n",
106
+ " with open(flag_file, \"w\") as f:\n",
107
+ " f.write(\">W<'\")\n",
108
+ "\n",
109
+ " print(\"🍪 Библиотеки установлены!\" + \" \"*35)\n",
110
+ " time.sleep(2)\n",
111
+ " clear_output()\n",
112
+ "\n",
113
+ "\n",
114
+ "# =================== OTHER ====================\n",
115
+ "# Setup Timer\n",
116
+ "start_colab = int(os.environ.get(\"START_COLAB\", time.time() - 5))\n",
117
+ "os.environ[\"START_COLAB\"] = str(start_colab)\n",
118
+ "\n",
119
+ "def download_cfg_files(file_paths, destination_path):\n",
120
+ " base_url = \"https://huggingface.co/NagisaNao/SD-CONFIGS/resolve/main\"\n",
121
+ " for filename in file_paths:\n",
122
+ " file_name = filename.split('/')[-1]\n",
123
+ " !wget -O {destination_path}/{file_name} {base_url}/{filename}\n",
124
+ "\n",
125
+ "def cfg_download():\n",
126
+ " common_files = [\"styles.csv\"]\n",
127
+ " a1111_files = [\"A1111/config.json\", \"A1111/ui-config.json\"]\n",
128
+ " forge_files = [\"reForge/config.json\", \"reForge/ui-config.json\"]\n",
129
+ "\n",
130
+ " with capture.capture_output():\n",
131
+ " download_cfg_files(common_files, webui_path)\n",
132
+ " ui_files = a1111_files if UI == 'A1111' else forge_files\n",
133
+ " download_cfg_files(ui_files, webui_path)\n",
134
+ "\n",
135
+ "def remove_dir(directory_path):\n",
136
+ " if directory_path and os.path.exists(directory_path):\n",
137
+ " try:\n",
138
+ " shutil.rmtree(directory_path)\n",
139
+ " except Exception:\n",
140
+ " !rm -rf {directory_path}\n",
141
+ "\n",
142
+ "TEMPORARY_DIR = f'{root_path}/temp_dir'\n",
143
+ "def copy_items_with_replace(src_base, dst_base):\n",
144
+ " items_to_copy = [\n",
145
+ " 'embeddings',\n",
146
+ " 'models/Stable-diffusion',\n",
147
+ " 'models/VAE',\n",
148
+ " 'models/Lora',\n",
149
+ " 'models/ControlNet'\n",
150
+ " ]\n",
151
+ "\n",
152
+ " print(\"⌚ Перемещение файлов...\", end='')\n",
153
+ " for item in items_to_copy:\n",
154
+ " src = os.path.join(src_base, item)\n",
155
+ " dst = os.path.join(dst_base, item)\n",
156
+ "\n",
157
+ " if os.path.exists(src):\n",
158
+ " if os.path.exists(dst):\n",
159
+ " remove_dir(dst)\n",
160
+ " os.makedirs(os.path.dirname(dst), exist_ok=True)\n",
161
+ " shutil.move(src, dst)\n",
162
+ " print(\"\\r🔥 Файлы перемещены!\" + \" \"*15)\n",
163
+ "\n",
164
+ "def handle_colab_timer(webui_path, timer_colab):\n",
165
+ " timer_file_path = os.path.join(webui_path, 'static', 'colabTimer.txt')\n",
166
+ " if not os.path.exists(timer_file_path):\n",
167
+ " with open(timer_file_path, 'w') as timer_file:\n",
168
+ " timer_file.write(str(timer_colab))\n",
169
+ " else:\n",
170
+ " with open(timer_file_path, 'r') as timer_file:\n",
171
+ " timer_colab = float(timer_file.read())\n",
172
+ " return timer_colab\n",
173
+ "\n",
174
+ "def unpack_webui():\n",
175
+ " start_install = time.time()\n",
176
+ " print(f\"⌚ Распаковка Stable Diffusion{' (Forge)' if UI == 'Forge' else ''}...\", end='')\n",
177
+ "\n",
178
+ " with capture.capture_output():\n",
179
+ " download_url = \"https://huggingface.co/NagisaNao/fast_repo/resolve/main/FULL_REPO.zip\"\n",
180
+ " if UI == 'Forge':\n",
181
+ " download_url = \"https://huggingface.co/NagisaNao/fast_repo/resolve/main/FULL_REPO_forge.zip\"\n",
182
+ "\n",
183
+ " zip_path = f\"{root_path}/repo.zip\"\n",
184
+ " !aria2c --console-log-level=error -c -x 16 -s 16 -k 1M {download_url} -d {root_path} -o repo.zip\n",
185
+ " !unzip -q -o {zip_path} -d {webui_path}\n",
186
+ " !rm -rf {zip_path}\n",
187
+ "\n",
188
+ " handle_colab_timer(webui_path, start_colab)\n",
189
+ "\n",
190
+ " install_time = time.time() - start_install\n",
191
+ " minutes, seconds = divmod(int(install_time), 60)\n",
192
+ " print(f\"\\r🚀 Распаковка Завершена! За {minutes:02}:{seconds:02} ⚡\" + \" \"*15)\n",
193
+ "\n",
194
+ " if os.path.exists(TEMPORARY_DIR):\n",
195
+ " copy_items_with_replace(TEMPORARY_DIR, webui_path)\n",
196
+ " remove_dir(TEMPORARY_DIR)\n",
197
+ "\n",
198
+ "# ================= MAIN CODE ==================\n",
199
+ "if os.path.exists(webui_path):\n",
200
+ " if UI != OLD_UI:\n",
201
+ " print(f'Переключение веб-интерфейса с \\033[33m{OLD_UI}\\033[0m на \\033[33m{UI}\\033[0m:')\n",
202
+ " copy_items_with_replace(webui_path, TEMPORARY_DIR)\n",
203
+ " remove_dir(webui_path)\n",
204
+ " os.environ['SDW_OLD_UI'] = UI\n",
205
+ " time.sleep(2)\n",
206
+ " clear_output()\n",
207
+ "\n",
208
+ "if not os.path.exists(webui_path):\n",
209
+ " unpack_webui()\n",
210
+ " cfg_download()\n",
211
+ "else:\n",
212
+ " print(\"🚀 Все распакованно... Пропуск. ⚡\")\n",
213
+ " timer_colab = handle_colab_timer(webui_path, start_colab)\n",
214
+ " elapsed_time = str(timedelta(seconds=time.time() - timer_colab)).split('.')[0]\n",
215
+ " print(f\"⌚️ Вы проводите эту сессию в течение - \\033[33m{elapsed_time}\\033[0m\")\n",
216
+ "\n",
217
+ "\n",
218
+ "## Changes extensions and WebUi\n",
219
+ "if latest_webui or latest_exstensions:\n",
220
+ " action = \"WebUI и Расширений\" if latest_webui and latest_exstensions else (\"WebUI\" if latest_webui else \"Расширений\")\n",
221
+ " print(f\"⌚️ Обновление {action}...\", end='')\n",
222
+ " with capture.capture_output():\n",
223
+ " !git config --global user.email \"[email protected]\"\n",
224
+ " !git config --global user.name \"Your Name\"\n",
225
+ "\n",
226
+ " ## Update Webui\n",
227
+ " if latest_webui:\n",
228
+ " %cd {webui_path}\n",
229
+ " !git restore .\n",
230
+ " !git pull -X theirs --rebase --autostash\n",
231
+ "\n",
232
+ " ## Update extensions\n",
233
+ " if latest_exstensions:\n",
234
+ " !{'for dir in ' + webui_path + '/extensions/*/; do cd \\\"$dir\\\" && git reset --hard && git pull; done'}\n",
235
+ " print(f\"\\r✨ Обновление {action} Завершено!\")\n",
236
+ "\n",
237
+ "\n",
238
+ "# === FIXING EXTENSIONS ===\n",
239
+ "anxety_repos = \"https://huggingface.co/NagisaNao/fast_repo/resolve/main\"\n",
240
+ "with capture.capture_output():\n",
241
+ " # --- Umi-Wildcard ---\n",
242
+ " !sed -i '521s/open=\\(False\\|True\\)/open=False/' {webui_path}/extensions/Umi-AI-Wildcards/scripts/wildcard_recursive.py # Closed accordion by default\n",
243
+ " # --- Encrypt-Image ---\n",
244
+ " !sed -i '9,37d' {webui_path}/extensions/Encrypt-Image/javascript/encrypt_images_info.js # Removes the weird text in webui\n",
245
+ "\n",
246
+ "\n",
247
+ "## Version switching\n",
248
+ "if commit_hash:\n",
249
+ " print('⏳ Активация машины времени...', end=\"\")\n",
250
+ " with capture.capture_output():\n",
251
+ " %cd {webui_path}\n",
252
+ " !git config --global user.email \"[email protected]\"\n",
253
+ " !git config --global user.name \"Your Name\"\n",
254
+ " !git reset --hard {commit_hash}\n",
255
+ " print(f\"\\r⌛️ Машина времени активированна! Текущий коммит: \\033[34m{commit_hash}\\033[0m\")\n",
256
+ "\n",
257
+ "\n",
258
+ "## Downloading model and stuff | oh~ Hey! If you're freaked out by that code too, don't worry, me too!\n",
259
+ "print(\"📦 Скачивание моделей и прочего...\", end='')\n",
260
+ "\n",
261
+ "extension_repo = []\n",
262
+ "PREFIXES = {\n",
263
+ " \"model\": models_dir,\n",
264
+ " \"vae\": vaes_dir,\n",
265
+ " \"lora\": loras_dir,\n",
266
+ " \"embed\": embeddings_dir,\n",
267
+ " \"extension\": extensions_dir,\n",
268
+ " \"control\": control_dir,\n",
269
+ " \"adetailer\": adetailer_dir,\n",
270
+ " \"config\": webui_path\n",
271
+ "}\n",
272
+ "!mkdir -p {\" \".join(PREFIXES.values())}\n",
273
+ "\n",
274
+ "''' Formatted Info Output '''\n",
275
+ "\n",
276
+ "def center_text(text, terminal_width=45):\n",
277
+ " padding = (terminal_width - len(text)) // 2\n",
278
+ " return f\"{' ' * padding}{text}{' ' * padding}\"\n",
279
+ "\n",
280
+ "def format_output(url, dst_dir, file_name, image_name=None, image_url=None):\n",
281
+ " info = center_text(f\"[{file_name.split('.')[0]}]\")\n",
282
+ " sep_line = '---' * 20\n",
283
+ "\n",
284
+ " print(f\"\\n\\033[32m{sep_line}\\033[36;1m{info}\\033[32m{sep_line}\\033[0m\")\n",
285
+ " print(f\"\\033[33mURL: {url}\")\n",
286
+ " print(f\"\\033[33mSAVE DIR: \\033[34m{dst_dir}\")\n",
287
+ " print(f\"\\033[33mFILE NAME: \\033[34m{file_name}\\033[0m\")\n",
288
+ " if 'civitai' in url and image_url:\n",
289
+ " print(f\"\\033[32m[Preview DL]:\\033[0m {image_name} - {image_url}\\n\")\n",
290
+ "\n",
291
+ "''' GET CivitAi API - DATA '''\n",
292
+ "\n",
293
+ "def CivitAi_API(url, file_name=None):\n",
294
+ " SUPPORT_TYPES = ('Checkpoint', 'TextualInversion', 'LORA')\n",
295
+ " CIVITAI_TOKEN = \"62c0c5956b2f9defbd844d754000180b\"\n",
296
+ "\n",
297
+ " url = url.split('?token=')[0] if '?token=' in url else url\n",
298
+ " url = url.replace('?type=', f'?token={CIVITAI_TOKEN}&type=') if '?type=' in url else f\"{url}?token={CIVITAI_TOKEN}\"\n",
299
+ "\n",
300
+ " def get_model_data(url):\n",
301
+ " base_url = \"https://civitai.com/api/v1\"\n",
302
+ " try:\n",
303
+ " if \"civitai.com/models/\" in url:\n",
304
+ " if '?modelVersionId=' in url:\n",
305
+ " version_id = url.split('?modelVersionId=')[1]\n",
306
+ " else:\n",
307
+ " model_id = url.split('/models/')[1].split('/')[0]\n",
308
+ " model_data = requests.get(f\"{base_url}/models/{model_id}\").json()\n",
309
+ " version_id = model_data['modelVersions'][0].get('id')\n",
310
+ " else:\n",
311
+ " version_id = url.split('/models/')[1].split('/')[0]\n",
312
+ "\n",
313
+ " return requests.get(f\"{base_url}/model-versions/{version_id}\").json()\n",
314
+ " except (KeyError, IndexError, requests.RequestException) as e:\n",
315
+ " return None\n",
316
+ "\n",
317
+ " data = get_model_data(url)\n",
318
+ "\n",
319
+ " if not data:\n",
320
+ " print(\"\\033[31m[Data Info]:\\033[0m Failed to retrieve data from the API.\\n\")\n",
321
+ " return 'None', None, None, None, None, None, None\n",
322
+ "\n",
323
+ " def get_model_info(url, data):\n",
324
+ " model_type = data['model']['type']\n",
325
+ " model_name = data['files'][0]['name']\n",
326
+ "\n",
327
+ " if 'type=' in url:\n",
328
+ " url_model_type = parse_qs(urlparse(url).query).get('type', [''])[0].lower()\n",
329
+ " if 'vae' in url_model_type:\n",
330
+ " model_type = data['files'][1]['type']\n",
331
+ " model_name = data['files'][1]['name']\n",
332
+ "\n",
333
+ " if file_name and '.' not in file_name:\n",
334
+ " file_extension = model_name.split('.')[-1]\n",
335
+ " model_name = f\"{file_name}.{file_extension}\"\n",
336
+ " elif file_name:\n",
337
+ " model_name = file_name\n",
338
+ "\n",
339
+ " return model_type, model_name\n",
340
+ "\n",
341
+ " def get_download_url(data, model_type):\n",
342
+ " if any(t.lower() in model_type.lower() for t in SUPPORT_TYPES):\n",
343
+ " return data['files'][0]['downloadUrl']\n",
344
+ "\n",
345
+ " return data['files'][1]['downloadUrl'] if 'type' in url else data['files'][0]['downloadUrl']\n",
346
+ "\n",
347
+ " def get_image_info(data, model_type, model_name):\n",
348
+ " if not any(t in model_type for t in SUPPORT_TYPES):\n",
349
+ " return None, None\n",
350
+ "\n",
351
+ " for image in data.get('images', []):\n",
352
+ " if image['nsfwLevel'] >= 4 and env == 'Kaggle': # Filter NSFW images for Kaggle\n",
353
+ " continue\n",
354
+ " image_url = image['url']\n",
355
+ " image_extension = image_url.split('.')[-1]\n",
356
+ " image_name = f\"{model_name.split('.')[0]}.preview.{image_extension}\" if image_url else None\n",
357
+ " return image_url, image_name\n",
358
+ " return None, None\n",
359
+ "\n",
360
+ " model_type, model_name = get_model_info(url, data)\n",
361
+ " download_url = get_download_url(data, model_type)\n",
362
+ " image_url, image_name = get_image_info(data, model_type, model_name)\n",
363
+ "\n",
364
+ " return f\"{download_url}{'&' if '?' in download_url else '?'}token={CIVITAI_TOKEN}\", download_url, model_type, model_name, image_url, image_name, data\n",
365
+ "\n",
366
+ "''' Main Download Code '''\n",
367
+ "\n",
368
+ "def strip_(url):\n",
369
+ " if 'github.com' in url:\n",
370
+ " return url.replace('/blob/', '/raw/')\n",
371
+ " elif \"huggingface.co\" in url:\n",
372
+ " url = url.replace('/blob/', '/resolve/')\n",
373
+ " return url.split('?')[0] if '?' in url else url\n",
374
+ " return url\n",
375
+ "\n",
376
+ "def download(url):\n",
377
+ " links_and_paths = [link_or_path.strip() for link_or_path in url.split(',') if link_or_path.strip()]\n",
378
+ "\n",
379
+ " for link_or_path in links_and_paths:\n",
380
+ " if any(link_or_path.lower().startswith(prefix) for prefix in PREFIXES):\n",
381
+ " handle_manual(link_or_path)\n",
382
+ " else:\n",
383
+ " url, dst_dir, file_name = link_or_path.split()\n",
384
+ " manual_download(url, dst_dir, file_name)\n",
385
+ "\n",
386
+ " # Unpuck ZIPs Files\n",
387
+ " for directory in PREFIXES.values():\n",
388
+ " for root, _, files in os.walk(directory):\n",
389
+ " for file in files:\n",
390
+ " if file.endswith(\".zip\"):\n",
391
+ " zip_path = os.path.join(root, file)\n",
392
+ " extract_path = os.path.splitext(zip_path)[0]\n",
393
+ " with zipfile.ZipFile(zip_path, 'r') as zip_ref:\n",
394
+ " zip_ref.extractall(extract_path)\n",
395
+ " os.remove(zip_path)\n",
396
+ "\n",
397
+ "def handle_manual(url):\n",
398
+ " url_parts = url.split(':', 1)\n",
399
+ " prefix, path = url_parts[0], url_parts[1]\n",
400
+ "\n",
401
+ " file_name_match = re.search(r'\\[(.*?)\\]', path)\n",
402
+ " file_name = file_name_match.group(1) if file_name_match else None\n",
403
+ " if file_name:\n",
404
+ " path = re.sub(r'\\[.*?\\]', '', path)\n",
405
+ "\n",
406
+ " if prefix in PREFIXES:\n",
407
+ " dir = PREFIXES[prefix]\n",
408
+ " if prefix != \"extension\":\n",
409
+ " try:\n",
410
+ " manual_download(path, dir, file_name=file_name, prefix=prefix)\n",
411
+ " except Exception as e:\n",
412
+ " print(f\"Error downloading file: {e}\")\n",
413
+ " else:\n",
414
+ " extension_repo.append((path, file_name))\n",
415
+ "\n",
416
+ "def manual_download(url, dst_dir, file_name, prefix=None):\n",
417
+ " hf_header = f\"--header='Authorization: Bearer {huggingface_token}'\" if huggingface_token else \"\"\n",
418
+ " aria2c_header = \"--header='User-Agent: Mozilla/5.0' --allow-overwrite=true\"\n",
419
+ " aria2_args = \"--optimize-concurrent-downloads --console-log-level=error --summary-interval=10 --stderr=true -c -x16 -s16 -k1M -j5\"\n",
420
+ "\n",
421
+ " clean_url = strip_(url)\n",
422
+ "\n",
423
+ " if 'civitai' in url:\n",
424
+ " url, clean_url, model_type, file_name, image_url, image_name, data = CivitAi_API(url, file_name)\n",
425
+ " if image_url and image_name:\n",
426
+ " command = [\"aria2c\"] + aria2_args.split() + [\"-d\", dst_dir, \"-o\", image_name, image_url]\n",
427
+ " subprocess.run(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n",
428
+ "\n",
429
+ " elif 'github' in url or 'huggingface.co' in url:\n",
430
+ " if file_name and '.' not in file_name:\n",
431
+ " file_extension = f\"{clean_url.split('/')[-1].split('.', 1)[1]}\"\n",
432
+ " file_name = f\"{file_name}.{file_extension}\"\n",
433
+ " if not file_name:\n",
434
+ " file_name = clean_url.split(\"/\")[-1]\n",
435
+ "\n",
436
+ " \"\"\" Formatted info output \"\"\"\n",
437
+ " try:\n",
438
+ " format_output(clean_url, dst_dir, file_name, image_name, image_url)\n",
439
+ " except UnboundLocalError:\n",
440
+ " format_output(clean_url, dst_dir, file_name, None, None)\n",
441
+ "\n",
442
+ " # =====================\n",
443
+ " def run_aria2c(url, dst_dir, file_name=None, args=\"\", header=\"\"):\n",
444
+ " file_path = os.path.join(dst_dir, file_name) # replaces config files\n",
445
+ " if os.path.exists(file_path) and prefix == 'config':\n",
446
+ " os.remove(file_path)\n",
447
+ "\n",
448
+ " out = f\"-o '{file_name}'\" if file_name else \"\"\n",
449
+ " !aria2c {header} {args} -d {dst_dir} {out} '{url}'\n",
450
+ "\n",
451
+ " # -- Google Drive --\n",
452
+ " if 'drive.google' in url:\n",
453
+ " if not globals().get('have_drive_link', False):\n",
454
+ " os.system(\"pip install -U gdown > /dev/null\")\n",
455
+ " globals()['have_drive_link'] = True\n",
456
+ "\n",
457
+ " if 'folders' in url:\n",
458
+ " os.system(f\"gdown --folder \\\"{url}\\\" -O {dst_dir} --fuzzy -c\")\n",
459
+ " else:\n",
460
+ " out_path = f\"{dst_dir}/{file_name}\" if file_name else dst_dir\n",
461
+ " os.system(f\"gdown \\\"{url}\\\" -O {out_path} --fuzzy -c\")\n",
462
+ "\n",
463
+ " # -- GitHub or Hugging Face --\n",
464
+ " elif 'github' in url or 'huggingface' in url:\n",
465
+ " run_aria2c(clean_url, dst_dir, file_name, aria2_args, hf_header if 'huggingface' in url else '')\n",
466
+ "\n",
467
+ " # -- Other HTTP/Sources --\n",
468
+ " elif 'http' in url:\n",
469
+ " run_aria2c(url, dst_dir, file_name, aria2_args, aria2c_header)\n",
470
+ "\n",
471
+ "''' SubModels - Added URLs '''\n",
472
+ "\n",
473
+ "# Separation of merged numbers\n",
474
+ "def split_numbers(num_str, max_num):\n",
475
+ " result = []\n",
476
+ " i = 0\n",
477
+ " while i < len(num_str):\n",
478
+ " found = False\n",
479
+ " for length in range(2, 0, -1):\n",
480
+ " if i + length <= len(num_str):\n",
481
+ " part = int(num_str[i:i + length])\n",
482
+ " if part <= max_num:\n",
483
+ " result.append(part)\n",
484
+ " i += length\n",
485
+ " found = True\n",
486
+ " break\n",
487
+ " if not found:\n",
488
+ " break\n",
489
+ " return result\n",
490
+ "\n",
491
+ "def add_submodels(selection, num_selection, model_dict, dst_dir):\n",
492
+ " if selection == \"none\":\n",
493
+ " return []\n",
494
+ " selected_models = []\n",
495
+ "\n",
496
+ " if selection == \"ALL\":\n",
497
+ " selected_models = sum(model_dict.values(), [])\n",
498
+ " else:\n",
499
+ " if selection in model_dict:\n",
500
+ " selected_models.extend(model_dict[selection])\n",
501
+ "\n",
502
+ " nums = num_selection.replace(',', ' ').split()\n",
503
+ " max_num = len(model_dict)\n",
504
+ " unique_nums = set()\n",
505
+ "\n",
506
+ " for num_part in nums:\n",
507
+ " split_nums = split_numbers(num_part, max_num)\n",
508
+ " unique_nums.update(split_nums)\n",
509
+ "\n",
510
+ " for num in unique_nums:\n",
511
+ " if 1 <= num <= max_num:\n",
512
+ " name = list(model_dict.keys())[num - 1]\n",
513
+ " selected_models.extend(model_dict[name])\n",
514
+ "\n",
515
+ " unique_models = {model['name']: model for model in selected_models}.values()\n",
516
+ "\n",
517
+ " for model in unique_models:\n",
518
+ " model['dst_dir'] = dst_dir\n",
519
+ "\n",
520
+ " return list(unique_models)\n",
521
+ "\n",
522
+ "def handle_submodels(selection, num_selection, model_dict, dst_dir, url):\n",
523
+ " submodels = add_submodels(selection, num_selection, model_dict, dst_dir)\n",
524
+ " for submodel in submodels:\n",
525
+ " if not inpainting_model and \"inpainting\" in submodel['name']:\n",
526
+ " continue\n",
527
+ " url += f\"{submodel['url']} {submodel['dst_dir']} {submodel['name']}, \"\n",
528
+ " return url\n",
529
+ "\n",
530
+ "url = \"\"\n",
531
+ "url = handle_submodels(model, model_num, model_list, models_dir, url)\n",
532
+ "url = handle_submodels(vae, vae_num, vae_list, vaes_dir, url)\n",
533
+ "url = handle_submodels(controlnet, controlnet_num, controlnet_list, control_dir, url)\n",
534
+ "\n",
535
+ "''' file.txt - added urls '''\n",
536
+ "\n",
537
+ "def process_file_download(file_url, PREFIXES, unique_urls):\n",
538
+ " files_urls = \"\"\n",
539
+ "\n",
540
+ " if file_url.startswith(\"http\"):\n",
541
+ " if \"blob\" in file_url:\n",
542
+ " file_url = file_url.replace(\"blob\", \"raw\")\n",
543
+ " response = requests.get(file_url)\n",
544
+ " lines = response.text.split('\\n')\n",
545
+ " else:\n",
546
+ " with open(file_url, 'r') as file:\n",
547
+ " lines = file.readlines()\n",
548
+ "\n",
549
+ " current_tag = None\n",
550
+ " for line in lines:\n",
551
+ " line = line.strip()\n",
552
+ " if any(f'# {tag}' in line.lower() for tag in PREFIXES):\n",
553
+ " current_tag = next((tag for tag in PREFIXES if tag in line.lower()))\n",
554
+ "\n",
555
+ " urls = [url.split('#')[0].strip() for url in line.split(',')] # filter urls\n",
556
+ " for url in urls:\n",
557
+ " filter_url = url.split('[')[0] # same url filter\n",
558
+ "\n",
559
+ " if url.startswith(\"http\") and filter_url not in unique_urls:\n",
560
+ " files_urls += f\"{current_tag}:{url}, \"\n",
561
+ " unique_urls.add(filter_url)\n",
562
+ "\n",
563
+ " return files_urls\n",
564
+ "\n",
565
+ "file_urls = \"\"\n",
566
+ "unique_urls = set()\n",
567
+ "\n",
568
+ "if custom_file_urls:\n",
569
+ " for custom_file_url in custom_file_urls.replace(',', '').split():\n",
570
+ " if not custom_file_url.endswith('.txt'):\n",
571
+ " custom_file_url += '.txt'\n",
572
+ " if not custom_file_url.startswith('http'):\n",
573
+ " if not custom_file_url.startswith(root_path):\n",
574
+ " custom_file_url = f'{root_path}/{custom_file_url}'\n",
575
+ "\n",
576
+ " try:\n",
577
+ " file_urls += process_file_download(custom_file_url, PREFIXES, unique_urls)\n",
578
+ " except FileNotFoundError:\n",
579
+ " pass\n",
580
+ "\n",
581
+ "# url prefixing\n",
582
+ "urls = (Model_url, Vae_url, LoRA_url, Embedding_url, Extensions_url)\n",
583
+ "prefixed_urls = (f\"{prefix}:{url}\" for prefix, url in zip(PREFIXES.keys(), urls) if url for url in url.replace(',', '').split())\n",
584
+ "url += \", \".join(prefixed_urls) + \", \" + file_urls\n",
585
+ "\n",
586
+ "if detailed_download == \"on\":\n",
587
+ " print(\"\\n\\n\\033[33m# ====== Подробная Загрузка ====== #\\n\\033[0m\")\n",
588
+ " download(url)\n",
589
+ " print(\"\\n\\033[33m# =============================== #\\n\\033[0m\")\n",
590
+ "else:\n",
591
+ " with capture.capture_output():\n",
592
+ " download(url)\n",
593
+ "\n",
594
+ "print(\"\\r🏁 Скачивание Завершено!\" + \" \"*15)\n",
595
+ "\n",
596
+ "\n",
597
+ "# Cleaning shit after downloading...\n",
598
+ "!find {webui_path} \\( -type d \\( -name \".ipynb_checkpoints\" -o -name \".aria2\" \\) -o -type f -name \"*.aria2\" \\) -exec rm -r {{}} \\; >/dev/null 2>&1\n",
599
+ "\n",
600
+ "\n",
601
+ "## Install of Custom extensions\n",
602
+ "if len(extension_repo) > 0:\n",
603
+ " print(\"✨ Установка кастомных расширений...\", end='')\n",
604
+ " with capture.capture_output():\n",
605
+ " for repo, repo_name in extension_repo:\n",
606
+ " if not repo_name:\n",
607
+ " repo_name = repo.split('/')[-1]\n",
608
+ " !cd {extensions_dir} \\\n",
609
+ " && git clone {repo} {repo_name} \\\n",
610
+ " && cd {repo_name} \\\n",
611
+ " && git fetch\n",
612
+ " print(f\"\\r📦 Установлено '{len(extension_repo)}', Кастомных расширений!\")\n",
613
+ "\n",
614
+ "\n",
615
+ "## List Models and stuff V2\n",
616
+ "if detailed_download == \"off\":\n",
617
+ " print(\"\\n\\n\\033[33mЕсли вы не видете каких-то скаченных файлов, включите в виджетах функцию 'Подробная Загрузка'.\")\n",
618
+ "\n",
619
+ "%run {root_path}/file_cell/special/dl_display_results.py # display widgets result"
620
+ ]
621
+ }
622
+ ],
623
+ "metadata": {
624
+ "colab": {
625
+ "provenance": []
626
+ },
627
+ "kernelspec": {
628
+ "display_name": "Python 3",
629
+ "name": "python3"
630
+ },
631
+ "language_info": {
632
+ "name": "python"
633
+ }
634
+ },
635
+ "nbformat": 4,
636
+ "nbformat_minor": 0
637
+ }
files_cells/notebooks/ru/launch_ru.ipynb ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "nbformat": 4,
3
+ "nbformat_minor": 0,
4
+ "metadata": {
5
+ "colab": {
6
+ "provenance": []
7
+ },
8
+ "kernelspec": {
9
+ "name": "python3",
10
+ "display_name": "Python 3"
11
+ },
12
+ "language_info": {
13
+ "name": "python"
14
+ }
15
+ },
16
+ "cells": [
17
+ {
18
+ "cell_type": "code",
19
+ "execution_count": null,
20
+ "metadata": {
21
+ "id": "JKTCrY9LU7Oq"
22
+ },
23
+ "outputs": [],
24
+ "source": [
25
+ "##~ LAUNCH CODE | BY: ANXETY ~##\n",
26
+ "\n",
27
+ "import os\n",
28
+ "import re\n",
29
+ "import time\n",
30
+ "import json\n",
31
+ "import requests\n",
32
+ "import subprocess\n",
33
+ "import cloudpickle as pickle\n",
34
+ "from datetime import timedelta\n",
35
+ "from IPython.display import clear_output\n",
36
+ "\n",
37
+ "\n",
38
+ "# Setup Env\n",
39
+ "env = os.getenv('ENV_NAME')\n",
40
+ "root_path = os.getenv('ROOT_PATH')\n",
41
+ "webui_path = os.getenv('WEBUI_PATH')\n",
42
+ "free_plan = os.getenv('FREE_PLAN')\n",
43
+ "\n",
44
+ "\n",
45
+ "def load_settings():\n",
46
+ " SETTINGS_FILE = f'{root_path}/settings.json'\n",
47
+ " if os.path.exists(SETTINGS_FILE):\n",
48
+ " with open(SETTINGS_FILE, 'r') as f:\n",
49
+ " return json.load(f)\n",
50
+ " return {}\n",
51
+ "\n",
52
+ "settings = load_settings()\n",
53
+ "ngrok_token = settings.get('ngrok_token', \"\")\n",
54
+ "zrok_token = settings.get('zrok_token', \"\")\n",
55
+ "commandline_arguments = settings.get('commandline_arguments', \"\")\n",
56
+ "change_webui = settings.get('change_webui', \"\")\n",
57
+ "\n",
58
+ "\n",
59
+ "# ========================== OTHER ==========================\n",
60
+ "def is_package_installed(package_name):\n",
61
+ " try:\n",
62
+ " subprocess.run([\"npm\", \"ls\", \"-g\", package_name], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n",
63
+ " return True\n",
64
+ " except subprocess.CalledProcessError:\n",
65
+ " return False\n",
66
+ "\n",
67
+ "lt_tunnel = is_package_installed('localtunnel')\n",
68
+ "\n",
69
+ "\n",
70
+ "# ======================== TUNNEL V2 ========================\n",
71
+ "print('Please Wait...')\n",
72
+ "\n",
73
+ "def get_public_ip(version='ipv4'):\n",
74
+ " try:\n",
75
+ " url = f'https://api64.ipify.org?format=json&{version}=true'\n",
76
+ " response = requests.get(url)\n",
77
+ " return response.json().get('ip', 'N/A')\n",
78
+ " except Exception as e:\n",
79
+ " print(f\"Error getting public {version} address:\", e)\n",
80
+ "\n",
81
+ "# Check if public IP is already saved, if not then get it\n",
82
+ "public_ip_file = f\"{root_path}/public_ip.txt\"\n",
83
+ "if os.path.exists(public_ip_file):\n",
84
+ " with open(public_ip_file, 'r') as file:\n",
85
+ " public_ipv4 = file.read().strip()\n",
86
+ "else:\n",
87
+ " public_ipv4 = get_public_ip(version='ipv4')\n",
88
+ " with open(public_ip_file, 'w') as file:\n",
89
+ " file.write(public_ipv4)\n",
90
+ "\n",
91
+ "tunnel_class = pickle.load(open(f\"{root_path}/new_tunnel\", \"rb\"), encoding=\"utf-8\")\n",
92
+ "tunnel_port = 1834\n",
93
+ "tunnel = tunnel_class(tunnel_port)\n",
94
+ "tunnel.add_tunnel(command=\"cl tunnel --url localhost:{port}\", name=\"cl\", pattern=re.compile(r\"[\\w-]+\\.trycloudflare\\.com\"))\n",
95
+ "\n",
96
+ "if lt_tunnel:\n",
97
+ " tunnel.add_tunnel(command=\"lt --port {port}\", name=\"lt\", pattern=re.compile(r\"[\\w-]+\\.loca\\.lt\"), note=\"Password : \" + \"\\033[32m\" + public_ipv4 + \"\\033[0m\" + \" rerun cell if 404 error.\")\n",
98
+ "\n",
99
+ "if zrok_token:\n",
100
+ " !zrok enable {zrok_token} &> /dev/null\n",
101
+ " tunnel.add_tunnel(command=\"zrok share public http://localhost:{port}/ --headless\", name=\"zrok\", pattern=re.compile(r\"[\\w-]+\\.share\\.zrok\\.io\"))\n",
102
+ "\n",
103
+ "clear_output()\n",
104
+ "\n",
105
+ "\n",
106
+ "# ================= Automatic Fixing Path V3 ================\n",
107
+ "paths_to_check = {\n",
108
+ " \"tagger_hf_cache_dir\": f\"{webui_path}/models/interrogators/\",\n",
109
+ " \"ad_extra_models_dir\": f\"{webui_path}/models/adetailer/\",\n",
110
+ " \"sd_checkpoint_hash\": \"\",\n",
111
+ " \"sd_model_checkpoint\": \"\",\n",
112
+ " \"sd_vae\": \"None\"\n",
113
+ "}\n",
114
+ "\n",
115
+ "config_path = f'{webui_path}/config.json'\n",
116
+ "\n",
117
+ "if os.path.exists(config_path):\n",
118
+ " with open(config_path, 'r') as file:\n",
119
+ " config_data = json.load(file)\n",
120
+ "\n",
121
+ " for key, value in paths_to_check.items():\n",
122
+ " if key in config_data and config_data[key] != value:\n",
123
+ " sed_command = f\"sed -i 's|\\\"{key}\\\": \\\".*\\\"|\\\"{key}\\\": \\\"{value}\\\"|' {config_path}\"\n",
124
+ " os.system(sed_command)\n",
125
+ "\n",
126
+ "\n",
127
+ "with tunnel:\n",
128
+ " %cd {webui_path}\n",
129
+ "\n",
130
+ " commandline_arguments += f' --port={tunnel_port}'\n",
131
+ " if ngrok_token:\n",
132
+ " commandline_arguments += f' --ngrok {ngrok_token}'\n",
133
+ " if env != \"Google Colab\":\n",
134
+ " commandline_arguments += f' --encrypt-pass={tunnel_port} --api'\n",
135
+ "\n",
136
+ " if change_webui == 'A1111':\n",
137
+ " commandline_arguments += ' --xformers'\n",
138
+ " else:\n",
139
+ " commandline_arguments += ' --disable-xformers --opt-sdp-attention --cuda-stream --pin-shared-memory'\n",
140
+ "\n",
141
+ " !COMMANDLINE_ARGS=\"{commandline_arguments}\" python launch.py\n",
142
+ "\n",
143
+ "start_colab = float(open(f'{webui_path}/static/colabTimer.txt', 'r').read())\n",
144
+ "time_since_start = str(timedelta(seconds=time.time()-start_colab)).split('.')[0]\n",
145
+ "print(f\"\\n⌚️ \\033[0mВы проводите эту сессию в течение - \\033[33m{time_since_start}\\033[0m\\n\\n\")\n",
146
+ "\n",
147
+ "if zrok_token:\n",
148
+ " !zrok disable &> /dev/null"
149
+ ]
150
+ }
151
+ ]
152
+ }
files_cells/notebooks/ru/widgets_ru.ipynb ADDED
@@ -0,0 +1,354 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "nbformat": 4,
3
+ "nbformat_minor": 0,
4
+ "metadata": {
5
+ "colab": {
6
+ "provenance": []
7
+ },
8
+ "kernelspec": {
9
+ "name": "python3",
10
+ "display_name": "Python 3"
11
+ },
12
+ "language_info": {
13
+ "name": "python"
14
+ }
15
+ },
16
+ "cells": [
17
+ {
18
+ "cell_type": "code",
19
+ "execution_count": null,
20
+ "metadata": {
21
+ "id": "JKTCrY9LU7Oq"
22
+ },
23
+ "outputs": [],
24
+ "source": [
25
+ "##~ WIDGET CODE | BY: ANXETY ~##\n",
26
+ "\n",
27
+ "import os\n",
28
+ "import json\n",
29
+ "import time\n",
30
+ "from ipywidgets import widgets\n",
31
+ "from IPython.display import display, HTML, Javascript, clear_output\n",
32
+ "\n",
33
+ "\n",
34
+ "# Setup Env\n",
35
+ "env = os.getenv('ENV_NAME')\n",
36
+ "root_path = os.getenv('ROOT_PATH')\n",
37
+ "webui_path = os.getenv('WEBUI_PATH')\n",
38
+ "free_plan = os.getenv('FREE_PLAN')\n",
39
+ "\n",
40
+ "\n",
41
+ "# ==================== CSS JS ====================\n",
42
+ "##~ custom background images V1.5 ~##\n",
43
+ "import argparse\n",
44
+ "parser = argparse.ArgumentParser(description='This script processes an background image.')\n",
45
+ "parser.add_argument('-i', '--image', type=str, help='URL of the image to process', metavar='')\n",
46
+ "parser.add_argument('-o', '--opacity', type=float, help='Opacity level for the image, between 0 and 1', metavar='', default=0.3)\n",
47
+ "parser.add_argument('-b', '--blur', type=str, help='Blur level for the image', metavar='', default=0)\n",
48
+ "parser.add_argument('-y', type=int, help='Y coordinate for the image in px', metavar='', default=0)\n",
49
+ "parser.add_argument('-x', type=int, help='X coordinate for the image in px', metavar='', default=0)\n",
50
+ "parser.add_argument('-s', '--scale', type=int, help='Scale image in %%', metavar='', default=100)\n",
51
+ "parser.add_argument('-m', '--mode', action='store_true', help='Removes repetitive image tiles')\n",
52
+ "parser.add_argument('-t', '--transparent', action='store_true', help='Makes input/selection fields 35%% more transparent')\n",
53
+ "parser.add_argument('-bf', '--blur-fields', type=str, help='Background blur level for input/selection fields', metavar='', default=2)\n",
54
+ "\n",
55
+ "args = parser.parse_args()\n",
56
+ "\n",
57
+ "url_img = args.image\n",
58
+ "opacity_img = args.opacity\n",
59
+ "blur_img = args.blur\n",
60
+ "y_img = args.y\n",
61
+ "x_img = args.x\n",
62
+ "scale_img = args.scale\n",
63
+ "blur_fields = args.blur_fields\n",
64
+ "\n",
65
+ "## ---\n",
66
+ "\"\"\" WTF KAGGLE - WHAT THE FUCK IS THE DIFFERENCE OF 35 PIXELS!?!?!? \"\"\"\n",
67
+ "fix_heigh_img = \"-810px\" if env == \"Kaggle\" else \"-775px\"\n",
68
+ "\n",
69
+ "\"\"\" transperent fields \"\"\"\n",
70
+ "t_bg_alpha = \"1\" if not args.transparent else \"0.65\"\n",
71
+ "\n",
72
+ "\"\"\" mode img - repeats \"\"\"\n",
73
+ "mode_img = \"repeat\" if not args.mode else \"no-repeat\"\n",
74
+ "\n",
75
+ "container_background = f'''\n",
76
+ "<style>\n",
77
+ ":root {{\n",
78
+ " /* for background container*/\n",
79
+ " --img_background: url({url_img});\n",
80
+ " --img_opacity: {opacity_img};\n",
81
+ " --img_blur: {blur_img}px;\n",
82
+ " --image_y: {y_img}px;\n",
83
+ " --image_x: {x_img}px;\n",
84
+ " --img_scale: {scale_img}%;\n",
85
+ " --img_mode: {mode_img};\n",
86
+ " --img_height_dif: {fix_heigh_img};\n",
87
+ "\n",
88
+ " /* for fields */\n",
89
+ " --bg-field-color: rgba(28, 28, 28, {t_bg_alpha}); /* -> #1c1c1c */\n",
90
+ " --bg-field-color-hover: rgba(38, 38, 38, {t_bg_alpha}); /* -> #262626; */\n",
91
+ " --bg-field-blur-level: {blur_fields}px;\n",
92
+ "}}\n",
93
+ "'''\n",
94
+ "\n",
95
+ "display(HTML(container_background))\n",
96
+ "\n",
97
+ "# Main CSS\n",
98
+ "css_file_path = f\"{root_path}/CSS/main_widgets.css\"\n",
99
+ "with open(css_file_path , \"r\") as f:\n",
100
+ " CSS = f.read()\n",
101
+ "display(HTML(f\"<style>{CSS}</style>\"))\n",
102
+ "\n",
103
+ "# Main JS\n",
104
+ "JS = '''\n",
105
+ "<!-- TOGGLE 'CustomDL' SCRIPT -->\n",
106
+ "<script>\n",
107
+ "function toggleContainer() {\n",
108
+ " let downloadContainer = document.querySelector('.container_custom_downlad');\n",
109
+ " let info = document.querySelector('.info');\n",
110
+ "\n",
111
+ " downloadContainer.classList.toggle('expanded');\n",
112
+ " info.classList.toggle('showed');\n",
113
+ "}\n",
114
+ "</script>\n",
115
+ "'''\n",
116
+ "display(HTML(JS))\n",
117
+ "\n",
118
+ "\n",
119
+ "# ==================== WIDGETS V2 ====================\n",
120
+ "HR = widgets.HTML('<hr>')\n",
121
+ "\n",
122
+ "class WidgetFactory:\n",
123
+ " def __init__(self, style=None, layout=None):\n",
124
+ " self.style = style if style else {'description_width': 'initial'}\n",
125
+ " self.layout = layout if layout else widgets.Layout(max_width='1080px', width='100%')\n",
126
+ "\n",
127
+ " def create_html(self, content, class_name=None):\n",
128
+ " html_widget = widgets.HTML(content)\n",
129
+ " if class_name:\n",
130
+ " html_widget.add_class(class_name)\n",
131
+ " return html_widget\n",
132
+ "\n",
133
+ " def create_header(self, name):\n",
134
+ " return widgets.HTML(f'<div class=\"header\">{name}<div>')\n",
135
+ "\n",
136
+ " def create_dropdown(self, options, value, description):\n",
137
+ " return widgets.Dropdown(options=options, value=value, description=description, style=self.style, layout=self.layout)\n",
138
+ "\n",
139
+ " def create_text(self, description, placeholder='', value=''):\n",
140
+ " return widgets.Text(description=description, placeholder=placeholder, value=value, style=self.style, layout=self.layout)\n",
141
+ "\n",
142
+ " def create_checkbox(self, value, description):\n",
143
+ " return widgets.Checkbox(value=value, description=description, style=self.style, layout=self.layout)\n",
144
+ "\n",
145
+ " def create_button(self, description, class_name=None):\n",
146
+ " button = widgets.Button(description=description)\n",
147
+ " if class_name:\n",
148
+ " button.add_class(class_name)\n",
149
+ " return button\n",
150
+ "\n",
151
+ " def create_hbox(self, children):\n",
152
+ " return widgets.HBox(children)\n",
153
+ "\n",
154
+ " def create_vbox(self, children, class_names=None):\n",
155
+ " vbox = widgets.VBox(children)\n",
156
+ " if class_names:\n",
157
+ " for class_name in class_names:\n",
158
+ " vbox.add_class(class_name)\n",
159
+ " return vbox\n",
160
+ "\n",
161
+ " def display(self, widget):\n",
162
+ " display(widget)\n",
163
+ "\n",
164
+ "# Instantiate the factory\n",
165
+ "factory = WidgetFactory()\n",
166
+ "\n",
167
+ "# --- MODEL ---\n",
168
+ "model_header = factory.create_header('Выбор Модели')\n",
169
+ "model_options = ['none',\n",
170
+ " '1.Anime (by XpucT) + INP',\n",
171
+ " '2.BluMix [Anime] [V7] + INP',\n",
172
+ " '3.Cetus-Mix [Anime] [V4] + INP',\n",
173
+ " '4.Counterfeit [Anime] [V3] + INP',\n",
174
+ " '5.CuteColor [Anime] [V3]',\n",
175
+ " '6.Dark-Sushi-Mix [Anime]',\n",
176
+ " '7.Deliberate [Realism] [V6] + INP',\n",
177
+ " '8.Meina-Mix [Anime] [V11] + INP',\n",
178
+ " '9.Mix-Pro [Anime] [V4] + INP']\n",
179
+ "model_widget = factory.create_dropdown(model_options, '4.Counterfeit [Anime] [V3] + INP', 'Модель:')\n",
180
+ "model_num_widget = factory.create_text('Номер Модели:', 'Введите номера моделей для скачивания через запятую/пробел.')\n",
181
+ "inpainting_model_widget = factory.create_checkbox(False, 'Inpainting Модели')\n",
182
+ "\n",
183
+ "# Display Model\n",
184
+ "all_model_box = factory.create_vbox([model_header, model_widget, model_num_widget, inpainting_model_widget], class_names=[\"container\", \"image_1\"])\n",
185
+ "factory.display(all_model_box)\n",
186
+ "\n",
187
+ "# --- VAE ---\n",
188
+ "vae_header = factory.create_header('Выбор VAE')\n",
189
+ "vae_options = ['none',\n",
190
+ " '1.Anime.vae',\n",
191
+ " '2.Anything.vae',\n",
192
+ " '3.Blessed2.vae',\n",
193
+ " '4.ClearVae.vae',\n",
194
+ " '5.WD.vae']\n",
195
+ "vae_widget = factory.create_dropdown(vae_options, '3.Blessed2.vae', 'Vae:')\n",
196
+ "vae_num_widget = factory.create_text('Номер Vae:', 'Введите номера vae для скачивания через запятую/пробел.')\n",
197
+ "\n",
198
+ "# Display Vae\n",
199
+ "all_vae_box = factory.create_vbox([vae_header, vae_widget, vae_num_widget], class_names=[\"container\", \"image_2\"])\n",
200
+ "factory.display(all_vae_box)\n",
201
+ "\n",
202
+ "# --- ADDITIONAL ---\n",
203
+ "additional_header = factory.create_header('Дополнительно')\n",
204
+ "latest_webui_widget = factory.create_checkbox(True, 'Обновить WebUI')\n",
205
+ "latest_exstensions_widget = factory.create_checkbox(True, 'Обновить Расширения')\n",
206
+ "change_webui_widget = factory.create_dropdown(['A1111', 'Forge'], 'A1111', 'Изменить WebUI:')\n",
207
+ "detailed_download_widget = factory.create_dropdown(['off', 'on'], 'off', 'Подробная Загрузка:')\n",
208
+ "choose_changes_widget = factory.create_hbox([latest_webui_widget, latest_exstensions_widget, change_webui_widget, detailed_download_widget])\n",
209
+ "\n",
210
+ "controlnet_options = ['none', 'ALL', '1.canny',\n",
211
+ " '2.openpose', '3.depth',\n",
212
+ " '4.normal_map', '5.mlsd',\n",
213
+ " '6.lineart', '7.soft_edge',\n",
214
+ " '8.scribble', '9.segmentation',\n",
215
+ " '10.shuffle', '11.tile',\n",
216
+ " '12.inpaint', '13.instruct_p2p']\n",
217
+ "controlnet_widget = factory.create_dropdown(controlnet_options, 'none', 'ControlNet:')\n",
218
+ "controlnet_num_widget = factory.create_text('Номер ControlNet:', 'Введите номера моделей ControlNet для скачивания через запятую/пробел.')\n",
219
+ "commit_hash_widget = factory.create_text('Commit Hash:')\n",
220
+ "huggingface_token_widget = factory.create_text('Токен HuggingFace:')\n",
221
+ "\n",
222
+ "ngrok_token_widget = factory.create_text('Токен Ngrok:')\n",
223
+ "ngrock_button = factory.create_html('<a href=\"https://dashboard.ngrok.com/get-started/your-authtoken\" target=\"_blank\">Получить Ngrok Токен</a>', class_name=\"button_ngrok\")\n",
224
+ "ngrok_widget = factory.create_hbox([ngrok_token_widget, ngrock_button])\n",
225
+ "\n",
226
+ "zrok_token_widget = factory.create_text('Токен Zrok:')\n",
227
+ "zrok_button = factory.create_html('<a href=\"https://colab.research.google.com/drive/1d2sjWDJi_GYBUavrHSuQyHTDuLy36WpU\" target=\"_blank\">Зарегать Zrok Токен</a>', class_name=\"button_ngrok\")\n",
228
+ "zrok_widget = factory.create_hbox([zrok_token_widget, zrok_button])\n",
229
+ "\n",
230
+ "commandline_arguments_options = \"--listen --enable-insecure-extension-access --theme dark --no-half-vae --disable-console-progressbars\"\n",
231
+ "commandline_arguments_widget = factory.create_text('Аргументы:', value=commandline_arguments_options)\n",
232
+ "\n",
233
+ "# Display Additional\n",
234
+ "additional_widget_list = [additional_header,\n",
235
+ " choose_changes_widget,\n",
236
+ " HR,\n",
237
+ " controlnet_widget,\n",
238
+ " controlnet_num_widget,\n",
239
+ " commit_hash_widget,\n",
240
+ " huggingface_token_widget,\n",
241
+ " ngrok_widget,\n",
242
+ " zrok_widget,\n",
243
+ " HR,\n",
244
+ " commandline_arguments_widget]\n",
245
+ "\n",
246
+ "if free_plan and env == \"Google Colab\": # remove ngrok from colab\n",
247
+ " additional_widget_list.remove(ngrok_widget)\n",
248
+ "\n",
249
+ "all_additional_box = factory.create_vbox(additional_widget_list, class_names=[\"container\", \"image_3\"])\n",
250
+ "factory.display(all_additional_box)\n",
251
+ "\n",
252
+ "# --- CUSTOM DOWNLOAD ---\n",
253
+ "custom_download_header_popup = factory.create_html('''\n",
254
+ "<style>\n",
255
+ "/* Term Colors */\n",
256
+ ".sample_label {color: #dbafff;}\n",
257
+ ".braces {color: #ffff00;}\n",
258
+ ".extension {color: #eb934b;}\n",
259
+ ".file_name {color: #ffffd8;}\n",
260
+ "</style>\n",
261
+ "\n",
262
+ "<div class=\"header\" style=\"cursor: pointer;\" onclick=\"toggleContainer()\">Кастомная Загрузка</div>\n",
263
+ "<!-- PopUp Window -->\n",
264
+ "<div class=\"info\" id=\"info_dl\">INFO</div>\n",
265
+ "<div class=\"popup\">\n",
266
+ " Разделите несколько URL-адресов запятой/пробелом. Для <span class=\"file_name\">пользовательского имени</span> файла/расширения укажите его через <span class=\"braces\">[]</span>\n",
267
+ " после URL без пробелов.\n",
268
+ " <span style=\"color: #ff9999\">Для файлов обязательно укажите</span> - <span class=\"extension\">Расширение Файла.</span>\n",
269
+ " <div class=\"sample\">\n",
270
+ " <span class=\"sample_label\">Пример для Файла:</span>\n",
271
+ " https://civitai.com/api/download/models/229782<span class=\"braces\">[</span><span class=\"file_name\">Detailer</span><span class=\"extension\">.safetensors</span><span class=\"braces\">]</span>\n",
272
+ " <br>\n",
273
+ " <span class=\"sample_label\">Пример для Расширения:</span>\n",
274
+ " https://github.com/hako-mikan/sd-webui-regional-prompter<span class=\"braces\">[</span><span class=\"file_name\">Regional-Prompter</span><span class=\"braces\">]</span>\n",
275
+ " </div>\n",
276
+ "</div>\n",
277
+ "''')\n",
278
+ "\n",
279
+ "Model_url_widget = factory.create_text('Model:')\n",
280
+ "Vae_url_widget = factory.create_text('Vae:')\n",
281
+ "LoRA_url_widget = factory.create_text('LoRa:')\n",
282
+ "Embedding_url_widget = factory.create_text('Embedding:')\n",
283
+ "Extensions_url_widget = factory.create_text('Extensions:')\n",
284
+ "custom_file_urls_widget = factory.create_text('Файл (txt):')\n",
285
+ "\n",
286
+ "# Display CustomDl\n",
287
+ "all_custom_box = factory.create_vbox([\n",
288
+ " custom_download_header_popup, Model_url_widget, Vae_url_widget, LoRA_url_widget, Embedding_url_widget, Extensions_url_widget, custom_file_urls_widget\n",
289
+ "], class_names=[\"container\", \"image_4\", \"container_custom_downlad\"])\n",
290
+ "factory.display(all_custom_box)\n",
291
+ "\n",
292
+ "# --- Save Button ---\n",
293
+ "save_button = factory.create_button('Сохранить', class_name=\"button_save\")\n",
294
+ "factory.display(save_button)\n",
295
+ "\n",
296
+ "\n",
297
+ "# ==================== OTHER FUNC ====================\n",
298
+ "# Setup UI\n",
299
+ "def setup_webui(change_webui_widget):\n",
300
+ " if 'SDW_UI' in os.environ:\n",
301
+ " UI = os.environ['SDW_UI']\n",
302
+ " else:\n",
303
+ " os.environ['SDW_UI'] = change_webui_widget\n",
304
+ " os.environ['SDW_OLD_UI'] = change_webui_widget\n",
305
+ "\n",
306
+ " UI = os.getenv('SDW_UI')\n",
307
+ "\n",
308
+ " if UI != change_webui_widget:\n",
309
+ " os.environ['SDW_UI'] = change_webui_widget\n",
310
+ "\n",
311
+ "\n",
312
+ "# ============ Load / Save - Settings V2 ============\n",
313
+ "SETTINGS_FILE = f'{root_path}/settings.json'\n",
314
+ "\n",
315
+ "SETTINGS_KEYS = [\n",
316
+ " 'model', 'model_num', 'inpainting_model',\n",
317
+ " 'vae', 'vae_num', 'latest_webui', 'latest_exstensions',\n",
318
+ " 'change_webui', 'detailed_download', 'controlnet',\n",
319
+ " 'controlnet_num', 'commit_hash', 'huggingface_token',\n",
320
+ " 'ngrok_token', 'zrok_token', 'commandline_arguments',\n",
321
+ " 'Model_url', 'Vae_url', 'LoRA_url', 'Embedding_url',\n",
322
+ " 'Extensions_url', 'custom_file_urls'\n",
323
+ "]\n",
324
+ "\n",
325
+ "def save_settings():\n",
326
+ " settings = {key: globals()[f\"{key}_widget\"].value for key in SETTINGS_KEYS}\n",
327
+ " with open(SETTINGS_FILE, 'w') as f:\n",
328
+ " json.dump(settings, f, indent=2)\n",
329
+ "\n",
330
+ "def load_settings():\n",
331
+ " if os.path.exists(SETTINGS_FILE):\n",
332
+ " with open(SETTINGS_FILE, 'r') as f:\n",
333
+ " settings = json.load(f)\n",
334
+ " for key in SETTINGS_KEYS:\n",
335
+ " globals()[f\"{key}_widget\"].value = settings.get(key, \"\")\n",
336
+ "\n",
337
+ "def hide_widgets():\n",
338
+ " widgets_list = [all_model_box, all_vae_box, all_additional_box, all_custom_box, save_button]\n",
339
+ " for widget in widgets_list:\n",
340
+ " widget.add_class(\"hide\")\n",
341
+ " time.sleep(0.5)\n",
342
+ " widgets.Widget.close_all()\n",
343
+ "\n",
344
+ "def save_data(button):\n",
345
+ " save_settings()\n",
346
+ " setup_webui(change_webui_widget.value)\n",
347
+ " hide_widgets()\n",
348
+ "\n",
349
+ "load_settings()\n",
350
+ "save_button.on_click(save_data)"
351
+ ]
352
+ }
353
+ ]
354
+ }
files_cells/python/en/auto_cleaner_en.py ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ##~ AutoCleaner V3.7 CODE | BY: ANXETY ~##
2
+
3
+ from directory_setup import models_dir, vaes_dir, control_dir, loras_dir, output_dir
4
+
5
+ import os
6
+ import time
7
+ from ipywidgets import widgets
8
+ from IPython.display import display, HTML, Javascript
9
+
10
+
11
+ # Setup Env
12
+ env = os.getenv('ENV_NAME')
13
+ root_path = os.getenv('ROOT_PATH')
14
+ webui_path = os.getenv('WEBUI_PATH')
15
+ free_plan = os.getenv('FREE_PLAN')
16
+
17
+
18
+ # ==================== CSS ====================
19
+ # Main CSS
20
+ css_file_path = f"{root_path}/CSS/auto_cleaner.css"
21
+ with open(css_file_path , "r") as f:
22
+ CSS_AC = f.read()
23
+ display(HTML(f"<style>{CSS_AC}</style>"))
24
+
25
+
26
+ # ================ AutoCleaner function ================
27
+ directories = {
28
+ "Images": output_dir,
29
+ "Models": models_dir,
30
+ "Vae": vaes_dir,
31
+ "LoRa": loras_dir,
32
+ "ControlNet Models": control_dir
33
+ }
34
+
35
+ """ functions """
36
+ def clean_directory(directory, directory_type):
37
+ deleted_files = 0
38
+
39
+ for root, dirs, files in os.walk(directory):
40
+ for file in files:
41
+ file_path = os.path.join(root, file)
42
+
43
+ if file.endswith(".txt"):
44
+ continue
45
+ if file.endswith((".safetensors", ".pt")) or directory_type == "Images":
46
+ deleted_files += 1
47
+
48
+ os.remove(file_path)
49
+ return deleted_files
50
+
51
+ def update_memory_info():
52
+ disk_space = psutil.disk_usage(os.getcwd())
53
+ total = disk_space.total / (1024 ** 3)
54
+ used = disk_space.used / (1024 ** 3)
55
+ free = disk_space.free / (1024 ** 3)
56
+
57
+ storage_info.value = f'''
58
+ <div class="storage_info_AC">Total storage: {total:.2f} GB <span style="color: #555">|</span> Used: {used:.2f} GB <span style="color: #555">|</span> Free: {free:.2f} GB</div>
59
+ '''
60
+
61
+ def on_execute_button_press(button):
62
+ selected_cleaners = auto_cleaner_widget.value
63
+ deleted_files_dict = {}
64
+
65
+ for option in selected_cleaners:
66
+ if option in directories:
67
+ deleted_files_dict[option] = clean_directory(directories[option], option)
68
+
69
+ output.clear_output()
70
+
71
+ with output:
72
+ for message in generate_messages(deleted_files_dict):
73
+ message_widget = HTML(f'<p class="output_message_AC">{message}</p>')
74
+ display(message_widget)
75
+
76
+ update_memory_info()
77
+
78
+ def on_clear_button_press(button):
79
+ container.add_class("hide")
80
+ time.sleep(0.5)
81
+ widgets.Widget.close_all()
82
+
83
+ def generate_messages(deleted_files_dict):
84
+ messages = []
85
+ word_variants = {
86
+ "Images": "Images",
87
+ "Models": "Models",
88
+ "Vae": "Vae",
89
+ "LoRa": "LoRa",
90
+ "ControlNet Models": "ControlNet Models"
91
+ }
92
+ for key, value in deleted_files_dict.items():
93
+ object_word = word_variants.get(key)
94
+ messages.append(f"Deleted {value} {object_word}")
95
+ return messages
96
+ # ================ AutoCleaner function ================
97
+
98
+
99
+ # --- storage memory ---
100
+ import psutil
101
+ disk_space = psutil.disk_usage(os.getcwd())
102
+ total = disk_space.total / (1024 ** 3)
103
+ used = disk_space.used / (1024 ** 3)
104
+ free = disk_space.free / (1024 ** 3)
105
+
106
+
107
+ # UI Code
108
+ AutoCleaner_options = AutoCleaner_options = list(directories.keys())
109
+ instruction_label = widgets.HTML('''
110
+ <span class="instruction_AC">Use <span style="color: #B2B2B2;">ctrl</span> or <span style="color: #B2B2B2;">shift</span> for multiple selections.</span>
111
+ ''')
112
+ auto_cleaner_widget = widgets.SelectMultiple(options=AutoCleaner_options, layout=widgets.Layout(width='auto')).add_class("custom-select-multiple_AC")
113
+ output = widgets.Output().add_class("output_AC")
114
+ # ---
115
+ execute_button = widgets.Button(description='Execute Cleaning').add_class("button_execute_AC").add_class("button_AC")
116
+ execute_button.on_click(on_execute_button_press)
117
+ clear_button = widgets.Button(description='Hide Widget').add_class("button_clear_AC").add_class("button_AC")
118
+ clear_button.on_click(on_clear_button_press)
119
+ # ---
120
+ storage_info = widgets.HTML(f'''
121
+ <div class="storage_info_AC">Total storage: {total:.2f} GB <span style="color: #555">|</span> Used: {used:.2f} GB <span style="color: #555">|</span> Free: {free:.2f} GB</div>
122
+ ''')
123
+ # ---
124
+ buttons = widgets.HBox([execute_button, clear_button])
125
+ lower_information_panel = widgets.HBox([buttons, storage_info]).add_class("lower_information_panel_AC")
126
+
127
+ container = widgets.VBox([instruction_label, widgets.HTML('<hr>'), auto_cleaner_widget, output, widgets.HTML('<hr>'), lower_information_panel]).add_class("container_AC")
128
+
129
+ display(container)
130
+
files_cells/python/en/downloading_en.py ADDED
@@ -0,0 +1,607 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ##~ DOWNLOADING CODE | BY: ANXETY ~##
2
+
3
+ from directory_setup import *
4
+ from models_data import model_list, vae_list, controlnet_list
5
+
6
+ import os
7
+ import re
8
+ import time
9
+ import json
10
+ import shutil
11
+ import zipfile
12
+ import requests
13
+ import subprocess
14
+ from datetime import timedelta
15
+ from subprocess import getoutput
16
+ from IPython.utils import capture
17
+ from IPython.display import clear_output
18
+ from urllib.parse import urlparse, parse_qs
19
+
20
+
21
+ # Setup Env
22
+ env = os.getenv('ENV_NAME')
23
+ root_path = os.getenv('ROOT_PATH')
24
+ webui_path = os.getenv('WEBUI_PATH')
25
+ free_plan = os.getenv('FREE_PLAN')
26
+
27
+ UI = os.getenv('SDW_UI')
28
+ OLD_UI = os.getenv('SDW_OLD_UI')
29
+
30
+ os.chdir(root_path)
31
+
32
+
33
+ # ============ loading settings V4 =============
34
+ def load_settings(path):
35
+ if os.path.exists(path):
36
+ with open(path, 'r') as file:
37
+ return json.load(file)
38
+ return {}
39
+
40
+ settings = load_settings(f'{root_path}/settings.json')
41
+
42
+ VARIABLES = [
43
+ 'model', 'model_num', 'inpainting_model',
44
+ 'vae', 'vae_num', 'latest_webui', 'latest_exstensions',
45
+ 'change_webui', 'detailed_download', 'controlnet',
46
+ 'controlnet_num', 'commit_hash', 'huggingface_token',
47
+ 'ngrok_token', 'zrok_token', 'commandline_arguments',
48
+ 'Model_url', 'Vae_url', 'LoRA_url', 'Embedding_url',
49
+ 'Extensions_url', 'custom_file_urls'
50
+ ]
51
+
52
+ locals().update({key: settings.get(key) for key in VARIABLES})
53
+
54
+
55
+ # ================ LIBRARIES V2 ================
56
+ flag_file = f"{root_path}/libraries_installed.txt"
57
+
58
+ if not os.path.exists(flag_file):
59
+ print("💿 Installing the libraries, it's going to take a while:\n")
60
+
61
+ install_lib = {
62
+ # "aria2": "apt -y install aria2",
63
+ "aria2": "pip install aria2",
64
+ "localtunnel": "npm install -g localtunnel",
65
+ }
66
+ if controlnet != 'none':
67
+ install_lib["insightface"] = "pip install insightface"
68
+
69
+ additional_libs = {
70
+ "Google Colab": {
71
+ "xformers": "pip install xformers==0.0.27 --no-deps"
72
+ },
73
+ "Kaggle": {
74
+ "xformers": "pip install xformers==0.0.26.post1",
75
+ # "torch": "pip install torch==2.1.2+cu121 torchvision==0.16.2+cu121 torchaudio==2.1.2 --extra-index-url https://download.pytorch.org/whl/cu121",
76
+ # "aiohttp": "pip install trash-cli && trash-put /opt/conda/lib/python3.10/site-packages/aiohttp*" # fix install req
77
+ }
78
+ }
79
+ if env in additional_libs:
80
+ install_lib.update(additional_libs[env])
81
+
82
+ # Loop through libraries
83
+ for index, (package, install_cmd) in enumerate(install_lib.items(), start=1):
84
+ print(f"\r[{index}/{len(install_lib)}] \033[32m>>\033[0m Installing \033[33m{package}\033[0m..." + " "*35, end='')
85
+ subprocess.run(install_cmd, shell=True, capture_output=True)
86
+
87
+ # Additional specific packages
88
+ with capture.capture_output():
89
+ get_ipython().system('curl -s -OL https://github.com/DEX-1101/sd-webui-notebook/raw/main/res/new_tunnel --output-dir {root_path}')
90
+ get_ipython().system('curl -s -Lo /usr/bin/cl https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 && chmod +x /usr/bin/cl')
91
+ get_ipython().system('curl -sLO https://github.com/openziti/zrok/releases/download/v0.4.32/zrok_0.4.32_linux_amd64.tar.gz && tar -xzf zrok_0.4.32_linux_amd64.tar.gz -C /usr/bin && rm -f zrok_0.4.32_linux_amd64.tar.gz')
92
+
93
+ clear_output()
94
+
95
+ # Save file install lib
96
+ with open(flag_file, "w") as f:
97
+ f.write(">W<'")
98
+
99
+ print("🍪 Libraries are installed!" + " "*35)
100
+ time.sleep(2)
101
+ clear_output()
102
+
103
+
104
+ # =================== OTHER ====================
105
+ # Setup Timer
106
+ start_colab = int(os.environ.get("START_COLAB", time.time() - 5))
107
+ os.environ["START_COLAB"] = str(start_colab)
108
+
109
+ def download_cfg_files(file_paths, destination_path):
110
+ base_url = "https://huggingface.co/NagisaNao/SD-CONFIGS/resolve/main"
111
+ for filename in file_paths:
112
+ file_name = filename.split('/')[-1]
113
+ get_ipython().system('wget -O {destination_path}/{file_name} {base_url}/{filename}')
114
+
115
+ def cfg_download():
116
+ common_files = ["styles.csv"]
117
+ a1111_files = ["A1111/config.json", "A1111/ui-config.json"]
118
+ forge_files = ["reForge/config.json", "reForge/ui-config.json"]
119
+
120
+ with capture.capture_output():
121
+ download_cfg_files(common_files, webui_path)
122
+ ui_files = a1111_files if UI == 'A1111' else forge_files
123
+ download_cfg_files(ui_files, webui_path)
124
+
125
+ def remove_dir(directory_path):
126
+ if directory_path and os.path.exists(directory_path):
127
+ try:
128
+ shutil.rmtree(directory_path)
129
+ except Exception:
130
+ get_ipython().system('rm -rf {directory_path}')
131
+
132
+ TEMPORARY_DIR = f'{root_path}/temp_dir'
133
+ def copy_items_with_replace(src_base, dst_base):
134
+ items_to_copy = [
135
+ 'embeddings',
136
+ 'models/Stable-diffusion',
137
+ 'models/VAE',
138
+ 'models/Lora',
139
+ 'models/ControlNet'
140
+ ]
141
+
142
+ print("⌚ Moving files...", end='')
143
+ for item in items_to_copy:
144
+ src = os.path.join(src_base, item)
145
+ dst = os.path.join(dst_base, item)
146
+
147
+ if os.path.exists(src):
148
+ if os.path.exists(dst):
149
+ remove_dir(dst)
150
+ os.makedirs(os.path.dirname(dst), exist_ok=True)
151
+ shutil.move(src, dst)
152
+ print("\r🔥 Files moved!" + " "*15)
153
+
154
+ def handle_colab_timer(webui_path, timer_colab):
155
+ timer_file_path = os.path.join(webui_path, 'static', 'colabTimer.txt')
156
+ if not os.path.exists(timer_file_path):
157
+ with open(timer_file_path, 'w') as timer_file:
158
+ timer_file.write(str(timer_colab))
159
+ else:
160
+ with open(timer_file_path, 'r') as timer_file:
161
+ timer_colab = float(timer_file.read())
162
+ return timer_colab
163
+
164
+ def unpack_webui():
165
+ start_install = time.time()
166
+ print(f"⌚ Unpacking Stable Diffusion{' (Forge)' if UI == 'Forge' else ''}...", end='')
167
+
168
+ with capture.capture_output():
169
+ download_url = "https://huggingface.co/NagisaNao/fast_repo/resolve/main/FULL_REPO.zip"
170
+ if UI == 'Forge':
171
+ download_url = "https://huggingface.co/NagisaNao/fast_repo/resolve/main/FULL_REPO_forge.zip"
172
+
173
+ zip_path = f"{root_path}/repo.zip"
174
+ get_ipython().system('aria2c --console-log-level=error -c -x 16 -s 16 -k 1M {download_url} -d {root_path} -o repo.zip')
175
+ get_ipython().system('unzip -q -o {zip_path} -d {webui_path}')
176
+ get_ipython().system('rm -rf {zip_path}')
177
+
178
+ handle_colab_timer(webui_path, start_colab)
179
+
180
+ install_time = time.time() - start_install
181
+ minutes, seconds = divmod(int(install_time), 60)
182
+ print(f"\r🚀 Unpacking complete! For {minutes:02}:{seconds:02} ⚡" + " "*15)
183
+
184
+ if os.path.exists(TEMPORARY_DIR):
185
+ copy_items_with_replace(TEMPORARY_DIR, webui_path)
186
+ remove_dir(TEMPORARY_DIR)
187
+
188
+ # ================= MAIN CODE ==================
189
+ if os.path.exists(webui_path):
190
+ if UI != OLD_UI:
191
+ print(f'Switching the WebUI from \033[33m{OLD_UI}\033[0m to \033[33m{UI}\033[0m:')
192
+ copy_items_with_replace(webui_path, TEMPORARY_DIR)
193
+ remove_dir(webui_path)
194
+ os.environ['SDW_OLD_UI'] = UI
195
+ time.sleep(2)
196
+ clear_output()
197
+
198
+ if not os.path.exists(webui_path):
199
+ unpack_webui()
200
+ cfg_download()
201
+ else:
202
+ print("🚀 All unpacked... Skip. ⚡")
203
+ timer_colab = handle_colab_timer(webui_path, start_colab)
204
+ elapsed_time = str(timedelta(seconds=time.time() - timer_colab)).split('.')[0]
205
+ print(f"⌚️ You have been conducting this session for - \033[33m{elapsed_time}\033[0m")
206
+
207
+
208
+ ## Changes extensions and WebUi
209
+ if latest_webui or latest_exstensions:
210
+ action = "WebUI and Extensions" if latest_webui and latest_exstensions else ("WebUI" if latest_webui else "Extensions")
211
+ print(f"⌚️ Updating {action}...", end='')
212
+ with capture.capture_output():
213
+ get_ipython().system('git config --global user.email "[email protected]"')
214
+ get_ipython().system('git config --global user.name "Your Name"')
215
+
216
+ ## Update Webui
217
+ if latest_webui:
218
+ get_ipython().run_line_magic('cd', '{webui_path}')
219
+ get_ipython().system('git restore .')
220
+ get_ipython().system('git pull -X theirs --rebase --autostash')
221
+
222
+ ## Update extensions
223
+ if latest_exstensions:
224
+ get_ipython().system('{\'for dir in \' + webui_path + \'/extensions/*/; do cd \\"$dir\\" && git reset --hard && git pull; done\'}')
225
+ print(f"\r✨ Updating {action} Completed!")
226
+
227
+
228
+ # === FIXING EXTENSIONS ===
229
+ anxety_repos = "https://huggingface.co/NagisaNao/fast_repo/resolve/main"
230
+ with capture.capture_output():
231
+ # --- Umi-Wildcard ---
232
+ get_ipython().system("sed -i '521s/open=\\(False\\|True\\)/open=False/' {webui_path}/extensions/Umi-AI-Wildcards/scripts/wildcard_recursive.py # Closed accordion by default")
233
+ # --- Encrypt-Image ---
234
+ get_ipython().system("sed -i '9,37d' {webui_path}/extensions/Encrypt-Image/javascript/encrypt_images_info.js # Removes the weird text in webui")
235
+
236
+
237
+ ## Version switching
238
+ if commit_hash:
239
+ print('⏳ Time machine activation...', end="")
240
+ with capture.capture_output():
241
+ get_ipython().run_line_magic('cd', '{webui_path}')
242
+ get_ipython().system('git config --global user.email "[email protected]"')
243
+ get_ipython().system('git config --global user.name "Your Name"')
244
+ get_ipython().system('git reset --hard {commit_hash}')
245
+ print(f"\r⌛️ The time machine has been activated! Current commit: \033[34m{commit_hash}\033[0m")
246
+
247
+
248
+ ## Downloading model and stuff | oh~ Hey! If you're freaked out by that code too, don't worry, me too!
249
+ print("📦 Downloading models and stuff...", end='')
250
+
251
+ extension_repo = []
252
+ PREFIXES = {
253
+ "model": models_dir,
254
+ "vae": vaes_dir,
255
+ "lora": loras_dir,
256
+ "embed": embeddings_dir,
257
+ "extension": extensions_dir,
258
+ "control": control_dir,
259
+ "adetailer": adetailer_dir,
260
+ "config": webui_path
261
+ }
262
+ get_ipython().system('mkdir -p {" ".join(PREFIXES.values())}')
263
+
264
+ ''' Formatted Info Output '''
265
+
266
+ def center_text(text, terminal_width=45):
267
+ padding = (terminal_width - len(text)) // 2
268
+ return f"{' ' * padding}{text}{' ' * padding}"
269
+
270
+ def format_output(url, dst_dir, file_name, image_name=None, image_url=None):
271
+ info = center_text(f"[{file_name.split('.')[0]}]")
272
+ sep_line = '---' * 20
273
+
274
+ print(f"\n\033[32m{sep_line}\033[36;1m{info}\033[32m{sep_line}\033[0m")
275
+ print(f"\033[33mURL: {url}")
276
+ print(f"\033[33mSAVE DIR: \033[34m{dst_dir}")
277
+ print(f"\033[33mFILE NAME: \033[34m{file_name}\033[0m")
278
+ if 'civitai' in url and image_url:
279
+ print(f"\033[32m[Preview DL]:\033[0m {image_name} - {image_url}\n")
280
+
281
+ ''' GET CivitAi API - DATA '''
282
+
283
+ def CivitAi_API(url, file_name=None):
284
+ SUPPORT_TYPES = ('Checkpoint', 'TextualInversion', 'LORA')
285
+ CIVITAI_TOKEN = "62c0c5956b2f9defbd844d754000180b"
286
+
287
+ url = url.split('?token=')[0] if '?token=' in url else url
288
+ url = url.replace('?type=', f'?token={CIVITAI_TOKEN}&type=') if '?type=' in url else f"{url}?token={CIVITAI_TOKEN}"
289
+
290
+ def get_model_data(url):
291
+ base_url = "https://civitai.com/api/v1"
292
+ try:
293
+ if "civitai.com/models/" in url:
294
+ if '?modelVersionId=' in url:
295
+ version_id = url.split('?modelVersionId=')[1]
296
+ else:
297
+ model_id = url.split('/models/')[1].split('/')[0]
298
+ model_data = requests.get(f"{base_url}/models/{model_id}").json()
299
+ version_id = model_data['modelVersions'][0].get('id')
300
+ else:
301
+ version_id = url.split('/models/')[1].split('/')[0]
302
+
303
+ return requests.get(f"{base_url}/model-versions/{version_id}").json()
304
+ except (KeyError, IndexError, requests.RequestException) as e:
305
+ return None
306
+
307
+ data = get_model_data(url)
308
+
309
+ if not data:
310
+ print("\033[31m[Data Info]:\033[0m Failed to retrieve data from the API.\n")
311
+ return 'None', None, None, None, None, None, None
312
+
313
+ def get_model_info(url, data):
314
+ model_type = data['model']['type']
315
+ model_name = data['files'][0]['name']
316
+
317
+ if 'type=' in url:
318
+ url_model_type = parse_qs(urlparse(url).query).get('type', [''])[0].lower()
319
+ if 'vae' in url_model_type:
320
+ model_type = data['files'][1]['type']
321
+ model_name = data['files'][1]['name']
322
+
323
+ if file_name and '.' not in file_name:
324
+ file_extension = model_name.split('.')[-1]
325
+ model_name = f"{file_name}.{file_extension}"
326
+ elif file_name:
327
+ model_name = file_name
328
+
329
+ return model_type, model_name
330
+
331
+ def get_download_url(data, model_type):
332
+ if any(t.lower() in model_type.lower() for t in SUPPORT_TYPES):
333
+ return data['files'][0]['downloadUrl']
334
+
335
+ return data['files'][1]['downloadUrl'] if 'type' in url else data['files'][0]['downloadUrl']
336
+
337
+ def get_image_info(data, model_type, model_name):
338
+ if not any(t in model_type for t in SUPPORT_TYPES):
339
+ return None, None
340
+
341
+ for image in data.get('images', []):
342
+ if image['nsfwLevel'] >= 4 and env == 'Kaggle': # Filter NSFW images for Kaggle
343
+ continue
344
+ image_url = image['url']
345
+ image_extension = image_url.split('.')[-1]
346
+ image_name = f"{model_name.split('.')[0]}.preview.{image_extension}" if image_url else None
347
+ return image_url, image_name
348
+ return None, None
349
+
350
+ model_type, model_name = get_model_info(url, data)
351
+ download_url = get_download_url(data, model_type)
352
+ image_url, image_name = get_image_info(data, model_type, model_name)
353
+
354
+ return f"{download_url}{'&' if '?' in download_url else '?'}token={CIVITAI_TOKEN}", download_url, model_type, model_name, image_url, image_name, data
355
+
356
+ ''' Main Download Code '''
357
+
358
+ def strip_(url):
359
+ if 'github.com' in url:
360
+ return url.replace('/blob/', '/raw/')
361
+ elif "huggingface.co" in url:
362
+ url = url.replace('/blob/', '/resolve/')
363
+ return url.split('?')[0] if '?' in url else url
364
+ return url
365
+
366
+ def download(url):
367
+ links_and_paths = [link_or_path.strip() for link_or_path in url.split(',') if link_or_path.strip()]
368
+
369
+ for link_or_path in links_and_paths:
370
+ if any(link_or_path.lower().startswith(prefix) for prefix in PREFIXES):
371
+ handle_manual(link_or_path)
372
+ else:
373
+ url, dst_dir, file_name = link_or_path.split()
374
+ manual_download(url, dst_dir, file_name)
375
+
376
+ # Unpuck ZIPs Files
377
+ for directory in PREFIXES.values():
378
+ for root, _, files in os.walk(directory):
379
+ for file in files:
380
+ if file.endswith(".zip"):
381
+ zip_path = os.path.join(root, file)
382
+ extract_path = os.path.splitext(zip_path)[0]
383
+ with zipfile.ZipFile(zip_path, 'r') as zip_ref:
384
+ zip_ref.extractall(extract_path)
385
+ os.remove(zip_path)
386
+
387
+ def handle_manual(url):
388
+ url_parts = url.split(':', 1)
389
+ prefix, path = url_parts[0], url_parts[1]
390
+
391
+ file_name_match = re.search(r'\[(.*?)\]', path)
392
+ file_name = file_name_match.group(1) if file_name_match else None
393
+ if file_name:
394
+ path = re.sub(r'\[.*?\]', '', path)
395
+
396
+ if prefix in PREFIXES:
397
+ dir = PREFIXES[prefix]
398
+ if prefix != "extension":
399
+ try:
400
+ manual_download(path, dir, file_name=file_name, prefix=prefix)
401
+ except Exception as e:
402
+ print(f"Error downloading file: {e}")
403
+ else:
404
+ extension_repo.append((path, file_name))
405
+
406
+ def manual_download(url, dst_dir, file_name, prefix=None):
407
+ hf_header = f"--header='Authorization: Bearer {huggingface_token}'" if huggingface_token else ""
408
+ aria2c_header = "--header='User-Agent: Mozilla/5.0' --allow-overwrite=true"
409
+ aria2_args = "--optimize-concurrent-downloads --console-log-level=error --summary-interval=10 --stderr=true -c -x16 -s16 -k1M -j5"
410
+
411
+ clean_url = strip_(url)
412
+
413
+ if 'civitai' in url:
414
+ url, clean_url, model_type, file_name, image_url, image_name, data = CivitAi_API(url, file_name)
415
+ if image_url and image_name:
416
+ command = ["aria2c"] + aria2_args.split() + ["-d", dst_dir, "-o", image_name, image_url]
417
+ subprocess.run(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
418
+
419
+ elif 'github' in url or 'huggingface.co' in url:
420
+ if file_name and '.' not in file_name:
421
+ file_extension = f"{clean_url.split('/')[-1].split('.', 1)[1]}"
422
+ file_name = f"{file_name}.{file_extension}"
423
+ if not file_name:
424
+ file_name = clean_url.split("/")[-1]
425
+
426
+ """ Formatted info output """
427
+ try:
428
+ format_output(clean_url, dst_dir, file_name, image_name, image_url)
429
+ except UnboundLocalError:
430
+ format_output(clean_url, dst_dir, file_name, None, None)
431
+
432
+ # =====================
433
+ def run_aria2c(url, dst_dir, file_name=None, args="", header=""):
434
+ file_path = os.path.join(dst_dir, file_name) # replaces config files
435
+ if os.path.exists(file_path) and prefix == 'config':
436
+ os.remove(file_path)
437
+
438
+ out = f"-o '{file_name}'" if file_name else ""
439
+ get_ipython().system("aria2c {header} {args} -d {dst_dir} {out} '{url}'")
440
+
441
+ # -- Google Drive --
442
+ if 'drive.google' in url:
443
+ if not globals().get('have_drive_link', False):
444
+ os.system("pip install -U gdown > /dev/null")
445
+ globals()['have_drive_link'] = True
446
+
447
+ if 'folders' in url:
448
+ os.system(f"gdown --folder \"{url}\" -O {dst_dir} --fuzzy -c")
449
+ else:
450
+ out_path = f"{dst_dir}/{file_name}" if file_name else dst_dir
451
+ os.system(f"gdown \"{url}\" -O {out_path} --fuzzy -c")
452
+
453
+ # -- GitHub or Hugging Face --
454
+ elif 'github' in url or 'huggingface' in url:
455
+ run_aria2c(clean_url, dst_dir, file_name, aria2_args, hf_header if 'huggingface' in url else '')
456
+
457
+ # -- Other HTTP/Sources --
458
+ elif 'http' in url:
459
+ run_aria2c(url, dst_dir, file_name, aria2_args, aria2c_header)
460
+
461
+ ''' SubModels - Added URLs '''
462
+
463
+ # Separation of merged numbers
464
+ def split_numbers(num_str, max_num):
465
+ result = []
466
+ i = 0
467
+ while i < len(num_str):
468
+ found = False
469
+ for length in range(2, 0, -1):
470
+ if i + length <= len(num_str):
471
+ part = int(num_str[i:i + length])
472
+ if part <= max_num:
473
+ result.append(part)
474
+ i += length
475
+ found = True
476
+ break
477
+ if not found:
478
+ break
479
+ return result
480
+
481
+ def add_submodels(selection, num_selection, model_dict, dst_dir):
482
+ if selection == "none":
483
+ return []
484
+ selected_models = []
485
+
486
+ if selection == "ALL":
487
+ selected_models = sum(model_dict.values(), [])
488
+ else:
489
+ if selection in model_dict:
490
+ selected_models.extend(model_dict[selection])
491
+
492
+ nums = num_selection.replace(',', ' ').split()
493
+ max_num = len(model_dict)
494
+ unique_nums = set()
495
+
496
+ for num_part in nums:
497
+ split_nums = split_numbers(num_part, max_num)
498
+ unique_nums.update(split_nums)
499
+
500
+ for num in unique_nums:
501
+ if 1 <= num <= max_num:
502
+ name = list(model_dict.keys())[num - 1]
503
+ selected_models.extend(model_dict[name])
504
+
505
+ unique_models = {model['name']: model for model in selected_models}.values()
506
+
507
+ for model in unique_models:
508
+ model['dst_dir'] = dst_dir
509
+
510
+ return list(unique_models)
511
+
512
+ def handle_submodels(selection, num_selection, model_dict, dst_dir, url):
513
+ submodels = add_submodels(selection, num_selection, model_dict, dst_dir)
514
+ for submodel in submodels:
515
+ if not inpainting_model and "inpainting" in submodel['name']:
516
+ continue
517
+ url += f"{submodel['url']} {submodel['dst_dir']} {submodel['name']}, "
518
+ return url
519
+
520
+ url = ""
521
+ url = handle_submodels(model, model_num, model_list, models_dir, url)
522
+ url = handle_submodels(vae, vae_num, vae_list, vaes_dir, url)
523
+ url = handle_submodels(controlnet, controlnet_num, controlnet_list, control_dir, url)
524
+
525
+ ''' file.txt - added urls '''
526
+
527
+ def process_file_download(file_url, PREFIXES, unique_urls):
528
+ files_urls = ""
529
+
530
+ if file_url.startswith("http"):
531
+ if "blob" in file_url:
532
+ file_url = file_url.replace("blob", "raw")
533
+ response = requests.get(file_url)
534
+ lines = response.text.split('\n')
535
+ else:
536
+ with open(file_url, 'r') as file:
537
+ lines = file.readlines()
538
+
539
+ current_tag = None
540
+ for line in lines:
541
+ line = line.strip()
542
+ if any(f'# {tag}' in line.lower() for tag in PREFIXES):
543
+ current_tag = next((tag for tag in PREFIXES if tag in line.lower()))
544
+
545
+ urls = [url.split('#')[0].strip() for url in line.split(',')] # filter urls
546
+ for url in urls:
547
+ filter_url = url.split('[')[0] # same url filter
548
+
549
+ if url.startswith("http") and filter_url not in unique_urls:
550
+ files_urls += f"{current_tag}:{url}, "
551
+ unique_urls.add(filter_url)
552
+
553
+ return files_urls
554
+
555
+ file_urls = ""
556
+ unique_urls = set()
557
+
558
+ if custom_file_urls:
559
+ for custom_file_url in custom_file_urls.replace(',', '').split():
560
+ if not custom_file_url.endswith('.txt'):
561
+ custom_file_url += '.txt'
562
+ if not custom_file_url.startswith('http'):
563
+ if not custom_file_url.startswith(root_path):
564
+ custom_file_url = f'{root_path}/{custom_file_url}'
565
+
566
+ try:
567
+ file_urls += process_file_download(custom_file_url, PREFIXES, unique_urls)
568
+ except FileNotFoundError:
569
+ pass
570
+
571
+ # url prefixing
572
+ urls = (Model_url, Vae_url, LoRA_url, Embedding_url, Extensions_url)
573
+ prefixed_urls = (f"{prefix}:{url}" for prefix, url in zip(PREFIXES.keys(), urls) if url for url in url.replace(',', '').split())
574
+ url += ", ".join(prefixed_urls) + ", " + file_urls
575
+
576
+ if detailed_download == "on":
577
+ print("\n\n\033[33m# ====== Detailed Download ====== #\n\033[0m")
578
+ download(url)
579
+ print("\n\033[33m# =============================== #\n\033[0m")
580
+ else:
581
+ with capture.capture_output():
582
+ download(url)
583
+
584
+ print("\r🏁 Download Complete!" + " "*15)
585
+
586
+
587
+ # Cleaning shit after downloading...
588
+ get_ipython().system('find {webui_path} \\( -type d \\( -name ".ipynb_checkpoints" -o -name ".aria2" \\) -o -type f -name "*.aria2" \\) -exec rm -r {{}} \\; >/dev/null 2>&1')
589
+
590
+
591
+ ## Install of Custom extensions
592
+ if len(extension_repo) > 0:
593
+ print("✨ Installing custom extensions...", end='')
594
+ with capture.capture_output():
595
+ for repo, repo_name in extension_repo:
596
+ if not repo_name:
597
+ repo_name = repo.split('/')[-1]
598
+ get_ipython().system('cd {extensions_dir} && git clone {repo} {repo_name} && cd {repo_name} && git fetch')
599
+ print(f"\r📦 Installed '{len(extension_repo)}', Custom extensions!")
600
+
601
+
602
+ ## List Models and stuff V2
603
+ if detailed_download == "off":
604
+ print("\n\n\033[33mIf you don't see any downloaded files, enable the 'Detailed Downloads' feature in the widget.")
605
+
606
+ get_ipython().run_line_magic('run', '{root_path}/file_cell/special/dl_display_results.py # display widgets result')
607
+
files_cells/python/en/launch_en.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ##~ LAUNCH CODE | BY: ANXETY ~##
2
+
3
+ import os
4
+ import re
5
+ import time
6
+ import json
7
+ import requests
8
+ import subprocess
9
+ import cloudpickle as pickle
10
+ from datetime import timedelta
11
+ from IPython.display import clear_output
12
+
13
+
14
+ # Setup Env
15
+ env = os.getenv('ENV_NAME')
16
+ root_path = os.getenv('ROOT_PATH')
17
+ webui_path = os.getenv('WEBUI_PATH')
18
+ free_plan = os.getenv('FREE_PLAN')
19
+
20
+
21
+ def load_settings():
22
+ SETTINGS_FILE = f'{root_path}/settings.json'
23
+ if os.path.exists(SETTINGS_FILE):
24
+ with open(SETTINGS_FILE, 'r') as f:
25
+ return json.load(f)
26
+ return {}
27
+
28
+ settings = load_settings()
29
+ ngrok_token = settings.get('ngrok_token', "")
30
+ zrok_token = settings.get('zrok_token', "")
31
+ commandline_arguments = settings.get('commandline_arguments', "")
32
+ change_webui = settings.get('change_webui', "")
33
+
34
+
35
+ # ========================== OTHER ==========================
36
+ def is_package_installed(package_name):
37
+ try:
38
+ subprocess.run(["npm", "ls", "-g", package_name], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
39
+ return True
40
+ except subprocess.CalledProcessError:
41
+ return False
42
+
43
+ lt_tunnel = is_package_installed('localtunnel')
44
+
45
+
46
+ # ======================== TUNNEL V2 ========================
47
+ print('Please Wait...')
48
+
49
+ def get_public_ip(version='ipv4'):
50
+ try:
51
+ url = f'https://api64.ipify.org?format=json&{version}=true'
52
+ response = requests.get(url)
53
+ return response.json().get('ip', 'N/A')
54
+ except Exception as e:
55
+ print(f"Error getting public {version} address:", e)
56
+
57
+ # Check if public IP is already saved, if not then get it
58
+ public_ip_file = f"{root_path}/public_ip.txt"
59
+ if os.path.exists(public_ip_file):
60
+ with open(public_ip_file, 'r') as file:
61
+ public_ipv4 = file.read().strip()
62
+ else:
63
+ public_ipv4 = get_public_ip(version='ipv4')
64
+ with open(public_ip_file, 'w') as file:
65
+ file.write(public_ipv4)
66
+
67
+ tunnel_class = pickle.load(open(f"{root_path}/new_tunnel", "rb"), encoding="utf-8")
68
+ tunnel_port = 1834
69
+ tunnel = tunnel_class(tunnel_port)
70
+ tunnel.add_tunnel(command="cl tunnel --url localhost:{port}", name="cl", pattern=re.compile(r"[\w-]+\.trycloudflare\.com"))
71
+
72
+ if lt_tunnel:
73
+ tunnel.add_tunnel(command="lt --port {port}", name="lt", pattern=re.compile(r"[\w-]+\.loca\.lt"), note="Password : " + "\033[32m" + public_ipv4 + "\033[0m" + " rerun cell if 404 error.")
74
+
75
+ if zrok_token:
76
+ get_ipython().system('zrok enable {zrok_token} &> /dev/null')
77
+ tunnel.add_tunnel(command="zrok share public http://localhost:{port}/ --headless", name="zrok", pattern=re.compile(r"[\w-]+\.share\.zrok\.io"))
78
+
79
+ clear_output()
80
+
81
+
82
+ # ================= Automatic Fixing Path V3 ================
83
+ paths_to_check = {
84
+ "tagger_hf_cache_dir": f"{webui_path}/models/interrogators/",
85
+ "ad_extra_models_dir": f"{webui_path}/models/adetailer/",
86
+ "sd_checkpoint_hash": "",
87
+ "sd_model_checkpoint": "",
88
+ "sd_vae": "None"
89
+ }
90
+
91
+ config_path = f'{webui_path}/config.json'
92
+
93
+ if os.path.exists(config_path):
94
+ with open(config_path, 'r') as file:
95
+ config_data = json.load(file)
96
+
97
+ for key, value in paths_to_check.items():
98
+ if key in config_data and config_data[key] != value:
99
+ sed_command = f"sed -i 's|\"{key}\": \".*\"|\"{key}\": \"{value}\"|' {config_path}"
100
+ os.system(sed_command)
101
+
102
+
103
+ with tunnel:
104
+ get_ipython().run_line_magic('cd', '{webui_path}')
105
+
106
+ commandline_arguments += f' --port={tunnel_port}'
107
+ if ngrok_token:
108
+ commandline_arguments += f' --ngrok {ngrok_token}'
109
+ if env != "Google Colab":
110
+ commandline_arguments += f' --encrypt-pass={tunnel_port} --api'
111
+
112
+ if change_webui == 'A1111':
113
+ commandline_arguments += ' --xformers'
114
+ else:
115
+ commandline_arguments += ' --disable-xformers --opt-sdp-attention --cuda-stream --pin-shared-memory'
116
+
117
+ get_ipython().system('COMMANDLINE_ARGS="{commandline_arguments}" python launch.py')
118
+
119
+ start_colab = float(open(f'{webui_path}/static/colabTimer.txt', 'r').read())
120
+ time_since_start = str(timedelta(seconds=time.time()-start_colab)).split('.')[0]
121
+ print(f"\n⌚️ \033[0mYou have been conducting this session for - \033[33m{time_since_start}\033[0m\n\n")
122
+
123
+ if zrok_token:
124
+ get_ipython().system('zrok disable &> /dev/null')
125
+
files_cells/python/en/widgets_en.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import time
4
+
5
+ # Setup Env
6
+ env = os.getenv('ENV_NAME')
7
+ root_path = os.getenv('ROOT_PATH')
8
+ webui_path = os.getenv('WEBUI_PATH')
9
+ free_plan = os.getenv('FREE_PLAN')
10
+
11
+ # Load Settings from JSON file
12
+ SETTINGS_FILE = f'{root_path}/settings.json'
13
+
14
+ def load_settings():
15
+ if os.path.exists(SETTINGS_FILE):
16
+ with open(SETTINGS_FILE, 'r') as f:
17
+ return json.load(f)
18
+ else:
19
+ raise FileNotFoundError(f"Settings file {SETTINGS_FILE} not found.")
20
+
21
+ settings = load_settings()
22
+
23
+ # Access the settings values directly from the `settings` dictionary
24
+ model = settings['model']
25
+ model_num = settings['model_num']
26
+ inpainting_model = settings['inpainting_model']
27
+ vae = settings['vae']
28
+ vae_num = settings['vae_num']
29
+ latest_webui = settings['latest_webui']
30
+ latest_exstensions = settings['latest_exstensions']
31
+ change_webui = settings['change_webui']
32
+ detailed_download = settings['detailed_download']
33
+ controlnet = settings['controlnet']
34
+ controlnet_num = settings['controlnet_num']
35
+ commit_hash = settings['commit_hash']
36
+ huggingface_token = settings['huggingface_token']
37
+ ngrok_token = settings['ngrok_token']
38
+ zrok_token = settings['zrok_token']
39
+ commandline_arguments = settings['commandline_arguments']
40
+ Model_url = settings['Model_url']
41
+ Vae_url = settings['Vae_url']
42
+ LoRA_url = settings['LoRA_url']
43
+ Embedding_url = settings['Embedding_url']
44
+ Extensions_url = settings['Extensions_url']
45
+ custom_file_urls = settings['custom_file_urls']
46
+
47
+ # Example function: Setup WebUI based on the loaded settings
48
+ def setup_webui():
49
+ UI = os.getenv('SDW_UI', change_webui)
50
+ if UI != change_webui:
51
+ os.environ['SDW_UI'] = change_webui
52
+
53
+ setup_webui()
54
+
55
+ # Main logic that depends on the settings
56
+ # print("Settings loaded and applied successfully.")
files_cells/python/ru/auto_cleaner_ru.py ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ##~ AutoCleaner V3.7 CODE | BY: ANXETY ~##
2
+
3
+ from directory_setup import models_dir, vaes_dir, control_dir, loras_dir, output_dir
4
+
5
+ import os
6
+ import time
7
+ from ipywidgets import widgets
8
+ from IPython.display import display, HTML
9
+
10
+
11
+ # Setup Env
12
+ env = os.getenv('ENV_NAME')
13
+ root_path = os.getenv('ROOT_PATH')
14
+ webui_path = os.getenv('WEBUI_PATH')
15
+ free_plan = os.getenv('FREE_PLAN')
16
+
17
+
18
+ # ==================== CSS ====================
19
+ # Main CSS
20
+ css_file_path = f"{root_path}/CSS/auto_cleaner.css"
21
+ with open(css_file_path , "r") as f:
22
+ CSS_AC = f.read()
23
+ display(HTML(f"<style>{CSS_AC}</style>"))
24
+
25
+
26
+ # ================ AutoCleaner function ================
27
+ directories = {
28
+ "Изображения": output_dir,
29
+ "Модели": models_dir,
30
+ "Vae": vaes_dir,
31
+ "LoRa": loras_dir,
32
+ "ControlNet Модели": control_dir
33
+ }
34
+
35
+ """ functions """
36
+ def clean_directory(directory, directory_type):
37
+ deleted_files = 0
38
+
39
+ for root, dirs, files in os.walk(directory):
40
+ for file in files:
41
+ file_path = os.path.join(root, file)
42
+
43
+ if file.endswith(".txt"):
44
+ continue
45
+ if file.endswith((".safetensors", ".pt")) or directory_type == "Images":
46
+ deleted_files += 1
47
+
48
+ os.remove(file_path)
49
+ return deleted_files
50
+
51
+ def update_memory_info():
52
+ disk_space = psutil.disk_usage(os.getcwd())
53
+ total = disk_space.total / (1024 ** 3)
54
+ used = disk_space.used / (1024 ** 3)
55
+ free = disk_space.free / (1024 ** 3)
56
+
57
+ storage_info.value = f'''
58
+ <div class="storage_info_AC">Всего: {total:.2f} GB <span style="color: #555">|</span> Используется: {used:.2f} GB <span style="color: #555">|</span> Свободно: {free:.2f} GB</div>
59
+ '''
60
+
61
+ def on_execute_button_press(button):
62
+ selected_cleaners = auto_cleaner_widget.value
63
+ deleted_files_dict = {}
64
+
65
+ for option in selected_cleaners:
66
+ if option in directories:
67
+ deleted_files_dict[option] = clean_directory(directories[option], option)
68
+
69
+ output.clear_output()
70
+
71
+ with output:
72
+ for message in generate_messages(deleted_files_dict):
73
+ message_widget = HTML(f'<p class="output_message_AC">{message}</p>')
74
+ display(message_widget)
75
+
76
+ update_memory_info()
77
+
78
+ def on_clear_button_press(button):
79
+ container.add_class("hide")
80
+ time.sleep(0.5)
81
+ widgets.Widget.close_all()
82
+
83
+ def generate_messages(deleted_files_dict):
84
+ messages = []
85
+ word_variants = {
86
+ "Изображения": "Изображений",
87
+ "Модели": "Моделей",
88
+ "Vae": "Vae",
89
+ "LoRa": "LoRa",
90
+ "ControlNet Модели": "ControlNet Моделей"
91
+ }
92
+ for key, value in deleted_files_dict.items():
93
+ object_word = word_variants.get(key)
94
+ messages.append(f"Удалено {value} {object_word}")
95
+ return messages
96
+
97
+
98
+ # --- storage memory ---
99
+ import psutil
100
+ disk_space = psutil.disk_usage(os.getcwd())
101
+ total = disk_space.total / (1024 ** 3)
102
+ used = disk_space.used / (1024 ** 3)
103
+ free = disk_space.free / (1024 ** 3)
104
+
105
+
106
+ # ================ Widgets ================
107
+ # UI Code
108
+ AutoCleaner_options = AutoCleaner_options = list(directories.keys())
109
+ instruction_label = widgets.HTML('''
110
+ <span class="instruction_AC">Используйте <span style="color: #B2B2B2;">ctrl</span> или <span style="color: #B2B2B2;">shift</span> для множественного выбора.</span>
111
+ ''')
112
+ auto_cleaner_widget = widgets.SelectMultiple(options=AutoCleaner_options, layout=widgets.Layout(width="auto")).add_class("custom-select-multiple_AC")
113
+ output = widgets.Output().add_class("output_AC")
114
+
115
+ execute_button = widgets.Button(description='Выполнить Очистку').add_class("button_execute_AC").add_class("button_AC")
116
+ execute_button.on_click(on_execute_button_press)
117
+ clear_button = widgets.Button(description='Скрыть Виджет').add_class("button_clear_AC").add_class("button_AC")
118
+ clear_button.on_click(on_clear_button_press)
119
+
120
+ storage_info = widgets.HTML(f'''
121
+ <div class="storage_info_AC">Всего: {total:.2f} GB <span style="color: #555">|</span> Используется: {used:.2f} GB <span style="color: #555">|</span> Свободно: {free:.2f} GB</div>
122
+ ''')
123
+
124
+ buttons = widgets.HBox([execute_button, clear_button])
125
+ lower_information_panel = widgets.HBox([buttons, storage_info]).add_class("lower_information_panel_AC")
126
+
127
+ container = widgets.VBox([instruction_label, widgets.HTML('<hr>'), auto_cleaner_widget, output, widgets.HTML('<hr>'), lower_information_panel]).add_class("container_AC")
128
+
129
+ display(container)
130
+
files_cells/python/ru/downloading_ru.py ADDED
@@ -0,0 +1,607 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ##~ DOWNLOADING CODE | BY: ANXETY ~##
2
+
3
+ from directory_setup import *
4
+ from models_data import model_list, vae_list, controlnet_list
5
+
6
+ import os
7
+ import re
8
+ import time
9
+ import json
10
+ import shutil
11
+ import zipfile
12
+ import requests
13
+ import subprocess
14
+ from datetime import timedelta
15
+ from subprocess import getoutput
16
+ from IPython.utils import capture
17
+ from IPython.display import clear_output
18
+ from urllib.parse import urlparse, parse_qs
19
+
20
+
21
+ # Setup Env
22
+ env = os.getenv('ENV_NAME')
23
+ root_path = os.getenv('ROOT_PATH')
24
+ webui_path = os.getenv('WEBUI_PATH')
25
+ free_plan = os.getenv('FREE_PLAN')
26
+
27
+ UI = os.getenv('SDW_UI')
28
+ OLD_UI = os.getenv('SDW_OLD_UI')
29
+
30
+ os.chdir(root_path)
31
+
32
+
33
+ # ============ loading settings V4 =============
34
+ def load_settings(path):
35
+ if os.path.exists(path):
36
+ with open(path, 'r') as file:
37
+ return json.load(file)
38
+ return {}
39
+
40
+ settings = load_settings(f'{root_path}/settings.json')
41
+
42
+ VARIABLES = [
43
+ 'model', 'model_num', 'inpainting_model',
44
+ 'vae', 'vae_num', 'latest_webui', 'latest_exstensions',
45
+ 'change_webui', 'detailed_download', 'controlnet',
46
+ 'controlnet_num', 'commit_hash', 'huggingface_token',
47
+ 'ngrok_token', 'zrok_token', 'commandline_arguments',
48
+ 'Model_url', 'Vae_url', 'LoRA_url', 'Embedding_url',
49
+ 'Extensions_url', 'custom_file_urls'
50
+ ]
51
+
52
+ locals().update({key: settings.get(key) for key in VARIABLES})
53
+
54
+
55
+ # ================ LIBRARIES V2 ================
56
+ flag_file = f"{root_path}/libraries_installed.txt"
57
+
58
+ if not os.path.exists(flag_file):
59
+ print("💿 Установка библиотек, это займет какое-то время:\n")
60
+
61
+ install_lib = {
62
+ # "aria2": "apt -y install aria2",
63
+ "aria2": "pip install aria2",
64
+ "localtunnel": "npm install -g localtunnel",
65
+ }
66
+ if controlnet != 'none':
67
+ install_lib["insightface"] = "pip install insightface"
68
+
69
+ additional_libs = {
70
+ "Google Colab": {
71
+ "xformers": "pip install xformers==0.0.27 --no-deps"
72
+ },
73
+ "Kaggle": {
74
+ "xformers": "pip install xformers==0.0.26.post1",
75
+ # "torch": "pip install torch==2.1.2+cu121 torchvision==0.16.2+cu121 torchaudio==2.1.2 --extra-index-url https://download.pytorch.org/whl/cu121",
76
+ # "aiohttp": "pip install trash-cli && trash-put /opt/conda/lib/python3.10/site-packages/aiohttp*" # fix install req
77
+ }
78
+ }
79
+ if env in additional_libs:
80
+ install_lib.update(additional_libs[env])
81
+
82
+ # Loop through libraries
83
+ for index, (package, install_cmd) in enumerate(install_lib.items(), start=1):
84
+ print(f"\r[{index}/{len(install_lib)}] \033[32m>>\033[0m Installing \033[33m{package}\033[0m..." + " "*35, end='')
85
+ subprocess.run(install_cmd, shell=True, capture_output=True)
86
+
87
+ # Additional specific packages
88
+ with capture.capture_output():
89
+ get_ipython().system('curl -s -OL https://github.com/DEX-1101/sd-webui-notebook/raw/main/res/new_tunnel --output-dir {root_path}')
90
+ get_ipython().system('curl -s -Lo /usr/bin/cl https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 && chmod +x /usr/bin/cl')
91
+ get_ipython().system('curl -sLO https://github.com/openziti/zrok/releases/download/v0.4.32/zrok_0.4.32_linux_amd64.tar.gz && tar -xzf zrok_0.4.32_linux_amd64.tar.gz -C /usr/bin && rm -f zrok_0.4.32_linux_amd64.tar.gz')
92
+
93
+ clear_output()
94
+
95
+ # Save file install lib
96
+ with open(flag_file, "w") as f:
97
+ f.write(">W<'")
98
+
99
+ print("🍪 Библиотеки установлены!" + " "*35)
100
+ time.sleep(2)
101
+ clear_output()
102
+
103
+
104
+ # =================== OTHER ====================
105
+ # Setup Timer
106
+ start_colab = int(os.environ.get("START_COLAB", time.time() - 5))
107
+ os.environ["START_COLAB"] = str(start_colab)
108
+
109
+ def download_cfg_files(file_paths, destination_path):
110
+ base_url = "https://huggingface.co/NagisaNao/SD-CONFIGS/resolve/main"
111
+ for filename in file_paths:
112
+ file_name = filename.split('/')[-1]
113
+ get_ipython().system('wget -O {destination_path}/{file_name} {base_url}/{filename}')
114
+
115
+ def cfg_download():
116
+ common_files = ["styles.csv"]
117
+ a1111_files = ["A1111/config.json", "A1111/ui-config.json"]
118
+ forge_files = ["reForge/config.json", "reForge/ui-config.json"]
119
+
120
+ with capture.capture_output():
121
+ download_cfg_files(common_files, webui_path)
122
+ ui_files = a1111_files if UI == 'A1111' else forge_files
123
+ download_cfg_files(ui_files, webui_path)
124
+
125
+ def remove_dir(directory_path):
126
+ if directory_path and os.path.exists(directory_path):
127
+ try:
128
+ shutil.rmtree(directory_path)
129
+ except Exception:
130
+ get_ipython().system('rm -rf {directory_path}')
131
+
132
+ TEMPORARY_DIR = f'{root_path}/temp_dir'
133
+ def copy_items_with_replace(src_base, dst_base):
134
+ items_to_copy = [
135
+ 'embeddings',
136
+ 'models/Stable-diffusion',
137
+ 'models/VAE',
138
+ 'models/Lora',
139
+ 'models/ControlNet'
140
+ ]
141
+
142
+ print("⌚ Перемещени�� файлов...", end='')
143
+ for item in items_to_copy:
144
+ src = os.path.join(src_base, item)
145
+ dst = os.path.join(dst_base, item)
146
+
147
+ if os.path.exists(src):
148
+ if os.path.exists(dst):
149
+ remove_dir(dst)
150
+ os.makedirs(os.path.dirname(dst), exist_ok=True)
151
+ shutil.move(src, dst)
152
+ print("\r🔥 Файлы перемещены!" + " "*15)
153
+
154
+ def handle_colab_timer(webui_path, timer_colab):
155
+ timer_file_path = os.path.join(webui_path, 'static', 'colabTimer.txt')
156
+ if not os.path.exists(timer_file_path):
157
+ with open(timer_file_path, 'w') as timer_file:
158
+ timer_file.write(str(timer_colab))
159
+ else:
160
+ with open(timer_file_path, 'r') as timer_file:
161
+ timer_colab = float(timer_file.read())
162
+ return timer_colab
163
+
164
+ def unpack_webui():
165
+ start_install = time.time()
166
+ print(f"⌚ Распаковка Stable Diffusion{' (Forge)' if UI == 'Forge' else ''}...", end='')
167
+
168
+ with capture.capture_output():
169
+ download_url = "https://huggingface.co/NagisaNao/fast_repo/resolve/main/FULL_REPO.zip"
170
+ if UI == 'Forge':
171
+ download_url = "https://huggingface.co/NagisaNao/fast_repo/resolve/main/FULL_REPO_forge.zip"
172
+
173
+ zip_path = f"{root_path}/repo.zip"
174
+ get_ipython().system('aria2c --console-log-level=error -c -x 16 -s 16 -k 1M {download_url} -d {root_path} -o repo.zip')
175
+ get_ipython().system('unzip -q -o {zip_path} -d {webui_path}')
176
+ get_ipython().system('rm -rf {zip_path}')
177
+
178
+ handle_colab_timer(webui_path, start_colab)
179
+
180
+ install_time = time.time() - start_install
181
+ minutes, seconds = divmod(int(install_time), 60)
182
+ print(f"\r🚀 Распаковка Завершена! За {minutes:02}:{seconds:02} ⚡" + " "*15)
183
+
184
+ if os.path.exists(TEMPORARY_DIR):
185
+ copy_items_with_replace(TEMPORARY_DIR, webui_path)
186
+ remove_dir(TEMPORARY_DIR)
187
+
188
+ # ================= MAIN CODE ==================
189
+ if os.path.exists(webui_path):
190
+ if UI != OLD_UI:
191
+ print(f'Переключение веб-интерфейса с \033[33m{OLD_UI}\033[0m на \033[33m{UI}\033[0m:')
192
+ copy_items_with_replace(webui_path, TEMPORARY_DIR)
193
+ remove_dir(webui_path)
194
+ os.environ['SDW_OLD_UI'] = UI
195
+ time.sleep(2)
196
+ clear_output()
197
+
198
+ if not os.path.exists(webui_path):
199
+ unpack_webui()
200
+ cfg_download()
201
+ else:
202
+ print("🚀 Все распакованно... Пропуск. ⚡")
203
+ timer_colab = handle_colab_timer(webui_path, start_colab)
204
+ elapsed_time = str(timedelta(seconds=time.time() - timer_colab)).split('.')[0]
205
+ print(f"⌚️ Вы проводите эту сессию в течение - \033[33m{elapsed_time}\033[0m")
206
+
207
+
208
+ ## Changes extensions and WebUi
209
+ if latest_webui or latest_exstensions:
210
+ action = "WebUI и Расширений" if latest_webui and latest_exstensions else ("WebUI" if latest_webui else "Расширений")
211
+ print(f"⌚️ Обновление {action}...", end='')
212
+ with capture.capture_output():
213
+ get_ipython().system('git config --global user.email "[email protected]"')
214
+ get_ipython().system('git config --global user.name "Your Name"')
215
+
216
+ ## Update Webui
217
+ if latest_webui:
218
+ get_ipython().run_line_magic('cd', '{webui_path}')
219
+ get_ipython().system('git restore .')
220
+ get_ipython().system('git pull -X theirs --rebase --autostash')
221
+
222
+ ## Update extensions
223
+ if latest_exstensions:
224
+ get_ipython().system('{\'for dir in \' + webui_path + \'/extensions/*/; do cd \\"$dir\\" && git reset --hard && git pull; done\'}')
225
+ print(f"\r✨ Обновление {action} Завершено!")
226
+
227
+
228
+ # === FIXING EXTENSIONS ===
229
+ anxety_repos = "https://huggingface.co/NagisaNao/fast_repo/resolve/main"
230
+ with capture.capture_output():
231
+ # --- Umi-Wildcard ---
232
+ get_ipython().system("sed -i '521s/open=\\(False\\|True\\)/open=False/' {webui_path}/extensions/Umi-AI-Wildcards/scripts/wildcard_recursive.py # Closed accordion by default")
233
+ # --- Encrypt-Image ---
234
+ get_ipython().system("sed -i '9,37d' {webui_path}/extensions/Encrypt-Image/javascript/encrypt_images_info.js # Removes the weird text in webui")
235
+
236
+
237
+ ## Version switching
238
+ if commit_hash:
239
+ print('⏳ Активация машины времени...', end="")
240
+ with capture.capture_output():
241
+ get_ipython().run_line_magic('cd', '{webui_path}')
242
+ get_ipython().system('git config --global user.email "[email protected]"')
243
+ get_ipython().system('git config --global user.name "Your Name"')
244
+ get_ipython().system('git reset --hard {commit_hash}')
245
+ print(f"\r⌛️ Машина времени активированна! Текущий коммит: \033[34m{commit_hash}\033[0m")
246
+
247
+
248
+ ## Downloading model and stuff | oh~ Hey! If you're freaked out by that code too, don't worry, me too!
249
+ print("📦 Скачивание моделей и прочего...", end='')
250
+
251
+ extension_repo = []
252
+ PREFIXES = {
253
+ "model": models_dir,
254
+ "vae": vaes_dir,
255
+ "lora": loras_dir,
256
+ "embed": embeddings_dir,
257
+ "extension": extensions_dir,
258
+ "control": control_dir,
259
+ "adetailer": adetailer_dir,
260
+ "config": webui_path
261
+ }
262
+ get_ipython().system('mkdir -p {" ".join(PREFIXES.values())}')
263
+
264
+ ''' Formatted Info Output '''
265
+
266
+ def center_text(text, terminal_width=45):
267
+ padding = (terminal_width - len(text)) // 2
268
+ return f"{' ' * padding}{text}{' ' * padding}"
269
+
270
+ def format_output(url, dst_dir, file_name, image_name=None, image_url=None):
271
+ info = center_text(f"[{file_name.split('.')[0]}]")
272
+ sep_line = '---' * 20
273
+
274
+ print(f"\n\033[32m{sep_line}\033[36;1m{info}\033[32m{sep_line}\033[0m")
275
+ print(f"\033[33mURL: {url}")
276
+ print(f"\033[33mSAVE DIR: \033[34m{dst_dir}")
277
+ print(f"\033[33mFILE NAME: \033[34m{file_name}\033[0m")
278
+ if 'civitai' in url and image_url:
279
+ print(f"\033[32m[Preview DL]:\033[0m {image_name} - {image_url}\n")
280
+
281
+ ''' GET CivitAi API - DATA '''
282
+
283
+ def CivitAi_API(url, file_name=None):
284
+ SUPPORT_TYPES = ('Checkpoint', 'TextualInversion', 'LORA')
285
+ CIVITAI_TOKEN = "62c0c5956b2f9defbd844d754000180b"
286
+
287
+ url = url.split('?token=')[0] if '?token=' in url else url
288
+ url = url.replace('?type=', f'?token={CIVITAI_TOKEN}&type=') if '?type=' in url else f"{url}?token={CIVITAI_TOKEN}"
289
+
290
+ def get_model_data(url):
291
+ base_url = "https://civitai.com/api/v1"
292
+ try:
293
+ if "civitai.com/models/" in url:
294
+ if '?modelVersionId=' in url:
295
+ version_id = url.split('?modelVersionId=')[1]
296
+ else:
297
+ model_id = url.split('/models/')[1].split('/')[0]
298
+ model_data = requests.get(f"{base_url}/models/{model_id}").json()
299
+ version_id = model_data['modelVersions'][0].get('id')
300
+ else:
301
+ version_id = url.split('/models/')[1].split('/')[0]
302
+
303
+ return requests.get(f"{base_url}/model-versions/{version_id}").json()
304
+ except (KeyError, IndexError, requests.RequestException) as e:
305
+ return None
306
+
307
+ data = get_model_data(url)
308
+
309
+ if not data:
310
+ print("\033[31m[Data Info]:\033[0m Failed to retrieve data from the API.\n")
311
+ return 'None', None, None, None, None, None, None
312
+
313
+ def get_model_info(url, data):
314
+ model_type = data['model']['type']
315
+ model_name = data['files'][0]['name']
316
+
317
+ if 'type=' in url:
318
+ url_model_type = parse_qs(urlparse(url).query).get('type', [''])[0].lower()
319
+ if 'vae' in url_model_type:
320
+ model_type = data['files'][1]['type']
321
+ model_name = data['files'][1]['name']
322
+
323
+ if file_name and '.' not in file_name:
324
+ file_extension = model_name.split('.')[-1]
325
+ model_name = f"{file_name}.{file_extension}"
326
+ elif file_name:
327
+ model_name = file_name
328
+
329
+ return model_type, model_name
330
+
331
+ def get_download_url(data, model_type):
332
+ if any(t.lower() in model_type.lower() for t in SUPPORT_TYPES):
333
+ return data['files'][0]['downloadUrl']
334
+
335
+ return data['files'][1]['downloadUrl'] if 'type' in url else data['files'][0]['downloadUrl']
336
+
337
+ def get_image_info(data, model_type, model_name):
338
+ if not any(t in model_type for t in SUPPORT_TYPES):
339
+ return None, None
340
+
341
+ for image in data.get('images', []):
342
+ if image['nsfwLevel'] >= 4 and env == 'Kaggle': # Filter NSFW images for Kaggle
343
+ continue
344
+ image_url = image['url']
345
+ image_extension = image_url.split('.')[-1]
346
+ image_name = f"{model_name.split('.')[0]}.preview.{image_extension}" if image_url else None
347
+ return image_url, image_name
348
+ return None, None
349
+
350
+ model_type, model_name = get_model_info(url, data)
351
+ download_url = get_download_url(data, model_type)
352
+ image_url, image_name = get_image_info(data, model_type, model_name)
353
+
354
+ return f"{download_url}{'&' if '?' in download_url else '?'}token={CIVITAI_TOKEN}", download_url, model_type, model_name, image_url, image_name, data
355
+
356
+ ''' Main Download Code '''
357
+
358
+ def strip_(url):
359
+ if 'github.com' in url:
360
+ return url.replace('/blob/', '/raw/')
361
+ elif "huggingface.co" in url:
362
+ url = url.replace('/blob/', '/resolve/')
363
+ return url.split('?')[0] if '?' in url else url
364
+ return url
365
+
366
+ def download(url):
367
+ links_and_paths = [link_or_path.strip() for link_or_path in url.split(',') if link_or_path.strip()]
368
+
369
+ for link_or_path in links_and_paths:
370
+ if any(link_or_path.lower().startswith(prefix) for prefix in PREFIXES):
371
+ handle_manual(link_or_path)
372
+ else:
373
+ url, dst_dir, file_name = link_or_path.split()
374
+ manual_download(url, dst_dir, file_name)
375
+
376
+ # Unpuck ZIPs Files
377
+ for directory in PREFIXES.values():
378
+ for root, _, files in os.walk(directory):
379
+ for file in files:
380
+ if file.endswith(".zip"):
381
+ zip_path = os.path.join(root, file)
382
+ extract_path = os.path.splitext(zip_path)[0]
383
+ with zipfile.ZipFile(zip_path, 'r') as zip_ref:
384
+ zip_ref.extractall(extract_path)
385
+ os.remove(zip_path)
386
+
387
+ def handle_manual(url):
388
+ url_parts = url.split(':', 1)
389
+ prefix, path = url_parts[0], url_parts[1]
390
+
391
+ file_name_match = re.search(r'\[(.*?)\]', path)
392
+ file_name = file_name_match.group(1) if file_name_match else None
393
+ if file_name:
394
+ path = re.sub(r'\[.*?\]', '', path)
395
+
396
+ if prefix in PREFIXES:
397
+ dir = PREFIXES[prefix]
398
+ if prefix != "extension":
399
+ try:
400
+ manual_download(path, dir, file_name=file_name, prefix=prefix)
401
+ except Exception as e:
402
+ print(f"Error downloading file: {e}")
403
+ else:
404
+ extension_repo.append((path, file_name))
405
+
406
+ def manual_download(url, dst_dir, file_name, prefix=None):
407
+ hf_header = f"--header='Authorization: Bearer {huggingface_token}'" if huggingface_token else ""
408
+ aria2c_header = "--header='User-Agent: Mozilla/5.0' --allow-overwrite=true"
409
+ aria2_args = "--optimize-concurrent-downloads --console-log-level=error --summary-interval=10 --stderr=true -c -x16 -s16 -k1M -j5"
410
+
411
+ clean_url = strip_(url)
412
+
413
+ if 'civitai' in url:
414
+ url, clean_url, model_type, file_name, image_url, image_name, data = CivitAi_API(url, file_name)
415
+ if image_url and image_name:
416
+ command = ["aria2c"] + aria2_args.split() + ["-d", dst_dir, "-o", image_name, image_url]
417
+ subprocess.run(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
418
+
419
+ elif 'github' in url or 'huggingface.co' in url:
420
+ if file_name and '.' not in file_name:
421
+ file_extension = f"{clean_url.split('/')[-1].split('.', 1)[1]}"
422
+ file_name = f"{file_name}.{file_extension}"
423
+ if not file_name:
424
+ file_name = clean_url.split("/")[-1]
425
+
426
+ """ Formatted info output """
427
+ try:
428
+ format_output(clean_url, dst_dir, file_name, image_name, image_url)
429
+ except UnboundLocalError:
430
+ format_output(clean_url, dst_dir, file_name, None, None)
431
+
432
+ # =====================
433
+ def run_aria2c(url, dst_dir, file_name=None, args="", header=""):
434
+ file_path = os.path.join(dst_dir, file_name) # replaces config files
435
+ if os.path.exists(file_path) and prefix == 'config':
436
+ os.remove(file_path)
437
+
438
+ out = f"-o '{file_name}'" if file_name else ""
439
+ get_ipython().system("aria2c {header} {args} -d {dst_dir} {out} '{url}'")
440
+
441
+ # -- Google Drive --
442
+ if 'drive.google' in url:
443
+ if not globals().get('have_drive_link', False):
444
+ os.system("pip install -U gdown > /dev/null")
445
+ globals()['have_drive_link'] = True
446
+
447
+ if 'folders' in url:
448
+ os.system(f"gdown --folder \"{url}\" -O {dst_dir} --fuzzy -c")
449
+ else:
450
+ out_path = f"{dst_dir}/{file_name}" if file_name else dst_dir
451
+ os.system(f"gdown \"{url}\" -O {out_path} --fuzzy -c")
452
+
453
+ # -- GitHub or Hugging Face --
454
+ elif 'github' in url or 'huggingface' in url:
455
+ run_aria2c(clean_url, dst_dir, file_name, aria2_args, hf_header if 'huggingface' in url else '')
456
+
457
+ # -- Other HTTP/Sources --
458
+ elif 'http' in url:
459
+ run_aria2c(url, dst_dir, file_name, aria2_args, aria2c_header)
460
+
461
+ ''' SubModels - Added URLs '''
462
+
463
+ # Separation of merged numbers
464
+ def split_numbers(num_str, max_num):
465
+ result = []
466
+ i = 0
467
+ while i < len(num_str):
468
+ found = False
469
+ for length in range(2, 0, -1):
470
+ if i + length <= len(num_str):
471
+ part = int(num_str[i:i + length])
472
+ if part <= max_num:
473
+ result.append(part)
474
+ i += length
475
+ found = True
476
+ break
477
+ if not found:
478
+ break
479
+ return result
480
+
481
+ def add_submodels(selection, num_selection, model_dict, dst_dir):
482
+ if selection == "none":
483
+ return []
484
+ selected_models = []
485
+
486
+ if selection == "ALL":
487
+ selected_models = sum(model_dict.values(), [])
488
+ else:
489
+ if selection in model_dict:
490
+ selected_models.extend(model_dict[selection])
491
+
492
+ nums = num_selection.replace(',', ' ').split()
493
+ max_num = len(model_dict)
494
+ unique_nums = set()
495
+
496
+ for num_part in nums:
497
+ split_nums = split_numbers(num_part, max_num)
498
+ unique_nums.update(split_nums)
499
+
500
+ for num in unique_nums:
501
+ if 1 <= num <= max_num:
502
+ name = list(model_dict.keys())[num - 1]
503
+ selected_models.extend(model_dict[name])
504
+
505
+ unique_models = {model['name']: model for model in selected_models}.values()
506
+
507
+ for model in unique_models:
508
+ model['dst_dir'] = dst_dir
509
+
510
+ return list(unique_models)
511
+
512
+ def handle_submodels(selection, num_selection, model_dict, dst_dir, url):
513
+ submodels = add_submodels(selection, num_selection, model_dict, dst_dir)
514
+ for submodel in submodels:
515
+ if not inpainting_model and "inpainting" in submodel['name']:
516
+ continue
517
+ url += f"{submodel['url']} {submodel['dst_dir']} {submodel['name']}, "
518
+ return url
519
+
520
+ url = ""
521
+ url = handle_submodels(model, model_num, model_list, models_dir, url)
522
+ url = handle_submodels(vae, vae_num, vae_list, vaes_dir, url)
523
+ url = handle_submodels(controlnet, controlnet_num, controlnet_list, control_dir, url)
524
+
525
+ ''' file.txt - added urls '''
526
+
527
+ def process_file_download(file_url, PREFIXES, unique_urls):
528
+ files_urls = ""
529
+
530
+ if file_url.startswith("http"):
531
+ if "blob" in file_url:
532
+ file_url = file_url.replace("blob", "raw")
533
+ response = requests.get(file_url)
534
+ lines = response.text.split('\n')
535
+ else:
536
+ with open(file_url, 'r') as file:
537
+ lines = file.readlines()
538
+
539
+ current_tag = None
540
+ for line in lines:
541
+ line = line.strip()
542
+ if any(f'# {tag}' in line.lower() for tag in PREFIXES):
543
+ current_tag = next((tag for tag in PREFIXES if tag in line.lower()))
544
+
545
+ urls = [url.split('#')[0].strip() for url in line.split(',')] # filter urls
546
+ for url in urls:
547
+ filter_url = url.split('[')[0] # same url filter
548
+
549
+ if url.startswith("http") and filter_url not in unique_urls:
550
+ files_urls += f"{current_tag}:{url}, "
551
+ unique_urls.add(filter_url)
552
+
553
+ return files_urls
554
+
555
+ file_urls = ""
556
+ unique_urls = set()
557
+
558
+ if custom_file_urls:
559
+ for custom_file_url in custom_file_urls.replace(',', '').split():
560
+ if not custom_file_url.endswith('.txt'):
561
+ custom_file_url += '.txt'
562
+ if not custom_file_url.startswith('http'):
563
+ if not custom_file_url.startswith(root_path):
564
+ custom_file_url = f'{root_path}/{custom_file_url}'
565
+
566
+ try:
567
+ file_urls += process_file_download(custom_file_url, PREFIXES, unique_urls)
568
+ except FileNotFoundError:
569
+ pass
570
+
571
+ # url prefixing
572
+ urls = (Model_url, Vae_url, LoRA_url, Embedding_url, Extensions_url)
573
+ prefixed_urls = (f"{prefix}:{url}" for prefix, url in zip(PREFIXES.keys(), urls) if url for url in url.replace(',', '').split())
574
+ url += ", ".join(prefixed_urls) + ", " + file_urls
575
+
576
+ if detailed_download == "on":
577
+ print("\n\n\033[33m# ====== Подробная Загрузка ====== #\n\033[0m")
578
+ download(url)
579
+ print("\n\033[33m# =============================== #\n\033[0m")
580
+ else:
581
+ with capture.capture_output():
582
+ download(url)
583
+
584
+ print("\r🏁 Скачивание Завершено!" + " "*15)
585
+
586
+
587
+ # Cleaning shit after downloading...
588
+ get_ipython().system('find {webui_path} \\( -type d \\( -name ".ipynb_checkpoints" -o -name ".aria2" \\) -o -type f -name "*.aria2" \\) -exec rm -r {{}} \\; >/dev/null 2>&1')
589
+
590
+
591
+ ## Install of Custom extensions
592
+ if len(extension_repo) > 0:
593
+ print("✨ Установка кастомных расширений...", end='')
594
+ with capture.capture_output():
595
+ for repo, repo_name in extension_repo:
596
+ if not repo_name:
597
+ repo_name = repo.split('/')[-1]
598
+ get_ipython().system('cd {extensions_dir} && git clone {repo} {repo_name} && cd {repo_name} && git fetch')
599
+ print(f"\r📦 Установлено '{len(extension_repo)}', Кастомных расширений!")
600
+
601
+
602
+ ## List Models and stuff V2
603
+ if detailed_download == "off":
604
+ print("\n\n\033[33mЕсли вы не видете каких-то скаченных файлов, включите в виджетах функцию 'Подробная Загрузка'.")
605
+
606
+ get_ipython().run_line_magic('run', '{root_path}/file_cell/special/dl_display_results.py # display widgets result')
607
+
files_cells/python/ru/launch_ru.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ##~ LAUNCH CODE | BY: ANXETY ~##
2
+
3
+ import os
4
+ import re
5
+ import time
6
+ import json
7
+ import requests
8
+ import subprocess
9
+ import cloudpickle as pickle
10
+ from datetime import timedelta
11
+ from IPython.display import clear_output
12
+
13
+
14
+ # Setup Env
15
+ env = os.getenv('ENV_NAME')
16
+ root_path = os.getenv('ROOT_PATH')
17
+ webui_path = os.getenv('WEBUI_PATH')
18
+ free_plan = os.getenv('FREE_PLAN')
19
+
20
+
21
+ def load_settings():
22
+ SETTINGS_FILE = f'{root_path}/settings.json'
23
+ if os.path.exists(SETTINGS_FILE):
24
+ with open(SETTINGS_FILE, 'r') as f:
25
+ return json.load(f)
26
+ return {}
27
+
28
+ settings = load_settings()
29
+ ngrok_token = settings.get('ngrok_token', "")
30
+ zrok_token = settings.get('zrok_token', "")
31
+ commandline_arguments = settings.get('commandline_arguments', "")
32
+ change_webui = settings.get('change_webui', "")
33
+
34
+
35
+ # ========================== OTHER ==========================
36
+ def is_package_installed(package_name):
37
+ try:
38
+ subprocess.run(["npm", "ls", "-g", package_name], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
39
+ return True
40
+ except subprocess.CalledProcessError:
41
+ return False
42
+
43
+ lt_tunnel = is_package_installed('localtunnel')
44
+
45
+
46
+ # ======================== TUNNEL V2 ========================
47
+ print('Please Wait...')
48
+
49
+ def get_public_ip(version='ipv4'):
50
+ try:
51
+ url = f'https://api64.ipify.org?format=json&{version}=true'
52
+ response = requests.get(url)
53
+ return response.json().get('ip', 'N/A')
54
+ except Exception as e:
55
+ print(f"Error getting public {version} address:", e)
56
+
57
+ # Check if public IP is already saved, if not then get it
58
+ public_ip_file = f"{root_path}/public_ip.txt"
59
+ if os.path.exists(public_ip_file):
60
+ with open(public_ip_file, 'r') as file:
61
+ public_ipv4 = file.read().strip()
62
+ else:
63
+ public_ipv4 = get_public_ip(version='ipv4')
64
+ with open(public_ip_file, 'w') as file:
65
+ file.write(public_ipv4)
66
+
67
+ tunnel_class = pickle.load(open(f"{root_path}/new_tunnel", "rb"), encoding="utf-8")
68
+ tunnel_port = 1834
69
+ tunnel = tunnel_class(tunnel_port)
70
+ tunnel.add_tunnel(command="cl tunnel --url localhost:{port}", name="cl", pattern=re.compile(r"[\w-]+\.trycloudflare\.com"))
71
+
72
+ if lt_tunnel:
73
+ tunnel.add_tunnel(command="lt --port {port}", name="lt", pattern=re.compile(r"[\w-]+\.loca\.lt"), note="Password : " + "\033[32m" + public_ipv4 + "\033[0m" + " rerun cell if 404 error.")
74
+
75
+ if zrok_token:
76
+ get_ipython().system('zrok enable {zrok_token} &> /dev/null')
77
+ tunnel.add_tunnel(command="zrok share public http://localhost:{port}/ --headless", name="zrok", pattern=re.compile(r"[\w-]+\.share\.zrok\.io"))
78
+
79
+ clear_output()
80
+
81
+
82
+ # ================= Automatic Fixing Path V3 ================
83
+ paths_to_check = {
84
+ "tagger_hf_cache_dir": f"{webui_path}/models/interrogators/",
85
+ "ad_extra_models_dir": f"{webui_path}/models/adetailer/",
86
+ "sd_checkpoint_hash": "",
87
+ "sd_model_checkpoint": "",
88
+ "sd_vae": "None"
89
+ }
90
+
91
+ config_path = f'{webui_path}/config.json'
92
+
93
+ if os.path.exists(config_path):
94
+ with open(config_path, 'r') as file:
95
+ config_data = json.load(file)
96
+
97
+ for key, value in paths_to_check.items():
98
+ if key in config_data and config_data[key] != value:
99
+ sed_command = f"sed -i 's|\"{key}\": \".*\"|\"{key}\": \"{value}\"|' {config_path}"
100
+ os.system(sed_command)
101
+
102
+
103
+ with tunnel:
104
+ get_ipython().run_line_magic('cd', '{webui_path}')
105
+
106
+ commandline_arguments += f' --port={tunnel_port}'
107
+ if ngrok_token:
108
+ commandline_arguments += f' --ngrok {ngrok_token}'
109
+ if env != "Google Colab":
110
+ commandline_arguments += f' --encrypt-pass={tunnel_port} --api'
111
+
112
+ if change_webui == 'A1111':
113
+ commandline_arguments += ' --xformers'
114
+ else:
115
+ commandline_arguments += ' --disable-xformers --opt-sdp-attention --cuda-stream --pin-shared-memory'
116
+
117
+ get_ipython().system('COMMANDLINE_ARGS="{commandline_arguments}" python launch.py')
118
+
119
+ start_colab = float(open(f'{webui_path}/static/colabTimer.txt', 'r').read())
120
+ time_since_start = str(timedelta(seconds=time.time()-start_colab)).split('.')[0]
121
+ print(f"\n⌚️ \033[0mВы проводите эту сессию в течение - \033[33m{time_since_start}\033[0m\n\n")
122
+
123
+ if zrok_token:
124
+ get_ipython().system('zrok disable &> /dev/null')
125
+
files_cells/python/ru/widgets_ru.py ADDED
@@ -0,0 +1,327 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ##~ WIDGET CODE | BY: ANXETY ~##
2
+
3
+ import os
4
+ import json
5
+ import time
6
+ from ipywidgets import widgets
7
+ from IPython.display import display, HTML, Javascript, clear_output
8
+
9
+
10
+ # Setup Env
11
+ env = os.getenv('ENV_NAME')
12
+ root_path = os.getenv('ROOT_PATH')
13
+ webui_path = os.getenv('WEBUI_PATH')
14
+ free_plan = os.getenv('FREE_PLAN')
15
+
16
+
17
+ # ==================== CSS JS ====================
18
+ ##~ custom background images V1.5 ~##
19
+ import argparse
20
+ parser = argparse.ArgumentParser(description='This script processes an background image.')
21
+ parser.add_argument('-i', '--image', type=str, help='URL of the image to process', metavar='')
22
+ parser.add_argument('-o', '--opacity', type=float, help='Opacity level for the image, between 0 and 1', metavar='', default=0.3)
23
+ parser.add_argument('-b', '--blur', type=str, help='Blur level for the image', metavar='', default=0)
24
+ parser.add_argument('-y', type=int, help='Y coordinate for the image in px', metavar='', default=0)
25
+ parser.add_argument('-x', type=int, help='X coordinate for the image in px', metavar='', default=0)
26
+ parser.add_argument('-s', '--scale', type=int, help='Scale image in %%', metavar='', default=100)
27
+ parser.add_argument('-m', '--mode', action='store_true', help='Removes repetitive image tiles')
28
+ parser.add_argument('-t', '--transparent', action='store_true', help='Makes input/selection fields 35%% more transparent')
29
+ parser.add_argument('-bf', '--blur-fields', type=str, help='Background blur level for input/selection fields', metavar='', default=2)
30
+
31
+ args = parser.parse_args()
32
+
33
+ url_img = args.image
34
+ opacity_img = args.opacity
35
+ blur_img = args.blur
36
+ y_img = args.y
37
+ x_img = args.x
38
+ scale_img = args.scale
39
+ blur_fields = args.blur_fields
40
+
41
+ ## ---
42
+ """ WTF KAGGLE - WHAT THE FUCK IS THE DIFFERENCE OF 35 PIXELS!?!?!? """
43
+ fix_heigh_img = "-810px" if env == "Kaggle" else "-775px"
44
+
45
+ """ transperent fields """
46
+ t_bg_alpha = "1" if not args.transparent else "0.65"
47
+
48
+ """ mode img - repeats """
49
+ mode_img = "repeat" if not args.mode else "no-repeat"
50
+
51
+ container_background = f'''
52
+ <style>
53
+ :root {{
54
+ /* for background container*/
55
+ --img_background: url({url_img});
56
+ --img_opacity: {opacity_img};
57
+ --img_blur: {blur_img}px;
58
+ --image_y: {y_img}px;
59
+ --image_x: {x_img}px;
60
+ --img_scale: {scale_img}%;
61
+ --img_mode: {mode_img};
62
+ --img_height_dif: {fix_heigh_img};
63
+
64
+ /* for fields */
65
+ --bg-field-color: rgba(28, 28, 28, {t_bg_alpha}); /* -> #1c1c1c */
66
+ --bg-field-color-hover: rgba(38, 38, 38, {t_bg_alpha}); /* -> #262626; */
67
+ --bg-field-blur-level: {blur_fields}px;
68
+ }}
69
+ '''
70
+
71
+ display(HTML(container_background))
72
+
73
+ # Main CSS
74
+ css_file_path = f"{root_path}/CSS/main_widgets.css"
75
+ with open(css_file_path , "r") as f:
76
+ CSS = f.read()
77
+ display(HTML(f"<style>{CSS}</style>"))
78
+
79
+ # Main JS
80
+ JS = '''
81
+ <!-- TOGGLE 'CustomDL' SCRIPT -->
82
+ <script>
83
+ function toggleContainer() {
84
+ let downloadContainer = document.querySelector('.container_custom_downlad');
85
+ let info = document.querySelector('.info');
86
+
87
+ downloadContainer.classList.toggle('expanded');
88
+ info.classList.toggle('showed');
89
+ }
90
+ </script>
91
+ '''
92
+ display(HTML(JS))
93
+
94
+
95
+ # ==================== WIDGETS V2 ====================
96
+ HR = widgets.HTML('<hr>')
97
+
98
+ class WidgetFactory:
99
+ def __init__(self, style=None, layout=None):
100
+ self.style = style if style else {'description_width': 'initial'}
101
+ self.layout = layout if layout else widgets.Layout(max_width='1080px', width='100%')
102
+
103
+ def create_html(self, content, class_name=None):
104
+ html_widget = widgets.HTML(content)
105
+ if class_name:
106
+ html_widget.add_class(class_name)
107
+ return html_widget
108
+
109
+ def create_header(self, name):
110
+ return widgets.HTML(f'<div class="header">{name}<div>')
111
+
112
+ def create_dropdown(self, options, value, description):
113
+ return widgets.Dropdown(options=options, value=value, description=description, style=self.style, layout=self.layout)
114
+
115
+ def create_text(self, description, placeholder='', value=''):
116
+ return widgets.Text(description=description, placeholder=placeholder, value=value, style=self.style, layout=self.layout)
117
+
118
+ def create_checkbox(self, value, description):
119
+ return widgets.Checkbox(value=value, description=description, style=self.style, layout=self.layout)
120
+
121
+ def create_button(self, description, class_name=None):
122
+ button = widgets.Button(description=description)
123
+ if class_name:
124
+ button.add_class(class_name)
125
+ return button
126
+
127
+ def create_hbox(self, children):
128
+ return widgets.HBox(children)
129
+
130
+ def create_vbox(self, children, class_names=None):
131
+ vbox = widgets.VBox(children)
132
+ if class_names:
133
+ for class_name in class_names:
134
+ vbox.add_class(class_name)
135
+ return vbox
136
+
137
+ def display(self, widget):
138
+ display(widget)
139
+
140
+ # Instantiate the factory
141
+ factory = WidgetFactory()
142
+
143
+ # --- MODEL ---
144
+ model_header = factory.create_header('Выбор Модели')
145
+ model_options = ['none',
146
+ '1.Anime (by XpucT) + INP',
147
+ '2.BluMix [Anime] [V7] + INP',
148
+ '3.Cetus-Mix [Anime] [V4] + INP',
149
+ '4.Counterfeit [Anime] [V3] + INP',
150
+ '5.CuteColor [Anime] [V3]',
151
+ '6.Dark-Sushi-Mix [Anime]',
152
+ '7.Deliberate [Realism] [V6] + INP',
153
+ '8.Meina-Mix [Anime] [V11] + INP',
154
+ '9.Mix-Pro [Anime] [V4] + INP']
155
+ model_widget = factory.create_dropdown(model_options, '4.Counterfeit [Anime] [V3] + INP', 'Модель:')
156
+ model_num_widget = factory.create_text('Номер Модели:', 'Введите номера моделей для скачивания через запятую/пробел.')
157
+ inpainting_model_widget = factory.create_checkbox(False, 'Inpainting Модели')
158
+
159
+ # Display Model
160
+ all_model_box = factory.create_vbox([model_header, model_widget, model_num_widget, inpainting_model_widget], class_names=["container", "image_1"])
161
+ factory.display(all_model_box)
162
+
163
+ # --- VAE ---
164
+ vae_header = factory.create_header('Выбор VAE')
165
+ vae_options = ['none',
166
+ '1.Anime.vae',
167
+ '2.Anything.vae',
168
+ '3.Blessed2.vae',
169
+ '4.ClearVae.vae',
170
+ '5.WD.vae']
171
+ vae_widget = factory.create_dropdown(vae_options, '3.Blessed2.vae', 'Vae:')
172
+ vae_num_widget = factory.create_text('Номер Vae:', 'Введите номера vae для скачивания через запятую/пробел.')
173
+
174
+ # Display Vae
175
+ all_vae_box = factory.create_vbox([vae_header, vae_widget, vae_num_widget], class_names=["container", "image_2"])
176
+ factory.display(all_vae_box)
177
+
178
+ # --- ADDITIONAL ---
179
+ additional_header = factory.create_header('Дополнительно')
180
+ latest_webui_widget = factory.create_checkbox(True, 'Обновить WebUI')
181
+ latest_exstensions_widget = factory.create_checkbox(True, 'Обновить Расширения')
182
+ change_webui_widget = factory.create_dropdown(['A1111', 'Forge'], 'A1111', 'Изменить WebUI:')
183
+ detailed_download_widget = factory.create_dropdown(['off', 'on'], 'off', 'Подробная Загрузка:')
184
+ choose_changes_widget = factory.create_hbox([latest_webui_widget, latest_exstensions_widget, change_webui_widget, detailed_download_widget])
185
+
186
+ controlnet_options = ['none', 'ALL', '1.canny',
187
+ '2.openpose', '3.depth',
188
+ '4.normal_map', '5.mlsd',
189
+ '6.lineart', '7.soft_edge',
190
+ '8.scribble', '9.segmentation',
191
+ '10.shuffle', '11.tile',
192
+ '12.inpaint', '13.instruct_p2p']
193
+ controlnet_widget = factory.create_dropdown(controlnet_options, 'none', 'ControlNet:')
194
+ controlnet_num_widget = factory.create_text('Номер ControlNet:', 'Введите номера моделей ControlNet для скачивания через запятую/пробел.')
195
+ commit_hash_widget = factory.create_text('Commit Hash:')
196
+ huggingface_token_widget = factory.create_text('Токен HuggingFace:')
197
+
198
+ ngrok_token_widget = factory.create_text('Токен Ngrok:')
199
+ ngrock_button = factory.create_html('<a href="https://dashboard.ngrok.com/get-started/your-authtoken" target="_blank">Получить Ngrok Токен</a>', class_name="button_ngrok")
200
+ ngrok_widget = factory.create_hbox([ngrok_token_widget, ngrock_button])
201
+
202
+ zrok_token_widget = factory.create_text('Токен Zrok:')
203
+ zrok_button = factory.create_html('<a href="https://colab.research.google.com/drive/1d2sjWDJi_GYBUavrHSuQyHTDuLy36WpU" target="_blank">Зарегать Zrok Токен</a>', class_name="button_ngrok")
204
+ zrok_widget = factory.create_hbox([zrok_token_widget, zrok_button])
205
+
206
+ commandline_arguments_options = "--listen --enable-insecure-extension-access --theme dark --no-half-vae --disable-console-progressbars"
207
+ commandline_arguments_widget = factory.create_text('Аргументы:', value=commandline_arguments_options)
208
+
209
+ # Display Additional
210
+ additional_widget_list = [additional_header,
211
+ choose_changes_widget,
212
+ HR,
213
+ controlnet_widget,
214
+ controlnet_num_widget,
215
+ commit_hash_widget,
216
+ huggingface_token_widget,
217
+ ngrok_widget,
218
+ zrok_widget,
219
+ HR,
220
+ commandline_arguments_widget]
221
+
222
+ if free_plan and env == "Google Colab": # remove ngrok from colab
223
+ additional_widget_list.remove(ngrok_widget)
224
+
225
+ all_additional_box = factory.create_vbox(additional_widget_list, class_names=["container", "image_3"])
226
+ factory.display(all_additional_box)
227
+
228
+ # --- CUSTOM DOWNLOAD ---
229
+ custom_download_header_popup = factory.create_html('''
230
+ <style>
231
+ /* Term Colors */
232
+ .sample_label {color: #dbafff;}
233
+ .braces {color: #ffff00;}
234
+ .extension {color: #eb934b;}
235
+ .file_name {color: #ffffd8;}
236
+ </style>
237
+
238
+ <div class="header" style="cursor: pointer;" onclick="toggleContainer()">Кастомная Загрузка</div>
239
+ <!-- PopUp Window -->
240
+ <div class="info" id="info_dl">INFO</div>
241
+ <div class="popup">
242
+ Разделите несколько URL-адресов запятой/пробелом. Для <span class="file_name">пользовательского имени</span> файла/расширения укажите его через <span class="braces">[]</span>
243
+ после URL без пробелов.
244
+ <span style="color: #ff9999">Для файлов обязательно укажите</span> - <span class="extension">Расширение Файла.</span>
245
+ <div class="sample">
246
+ <span class="sample_label">Пример для Файла:</span>
247
+ https://civitai.com/api/download/models/229782<span class="braces">[</span><span class="file_name">Detailer</span><span class="extension">.safetensors</span><span class="braces">]</span>
248
+ <br>
249
+ <span class="sample_label">Пример для Расширения:</span>
250
+ https://github.com/hako-mikan/sd-webui-regional-prompter<span class="braces">[</span><span class="file_name">Regional-Prompter</span><span class="braces">]</span>
251
+ </div>
252
+ </div>
253
+ ''')
254
+
255
+ Model_url_widget = factory.create_text('Model:')
256
+ Vae_url_widget = factory.create_text('Vae:')
257
+ LoRA_url_widget = factory.create_text('LoRa:')
258
+ Embedding_url_widget = factory.create_text('Embedding:')
259
+ Extensions_url_widget = factory.create_text('Extensions:')
260
+ custom_file_urls_widget = factory.create_text('Файл (txt):')
261
+
262
+ # Display CustomDl
263
+ all_custom_box = factory.create_vbox([
264
+ custom_download_header_popup, Model_url_widget, Vae_url_widget, LoRA_url_widget, Embedding_url_widget, Extensions_url_widget, custom_file_urls_widget
265
+ ], class_names=["container", "image_4", "container_custom_downlad"])
266
+ factory.display(all_custom_box)
267
+
268
+ # --- Save Button ---
269
+ save_button = factory.create_button('Сохранить', class_name="button_save")
270
+ factory.display(save_button)
271
+
272
+
273
+ # ==================== OTHER FUNC ====================
274
+ # Setup UI
275
+ def setup_webui(change_webui_widget):
276
+ if 'SDW_UI' in os.environ:
277
+ UI = os.environ['SDW_UI']
278
+ else:
279
+ os.environ['SDW_UI'] = change_webui_widget
280
+ os.environ['SDW_OLD_UI'] = change_webui_widget
281
+
282
+ UI = os.getenv('SDW_UI')
283
+
284
+ if UI != change_webui_widget:
285
+ os.environ['SDW_UI'] = change_webui_widget
286
+
287
+
288
+ # ============ Load / Save - Settings V2 ============
289
+ SETTINGS_FILE = f'{root_path}/settings.json'
290
+
291
+ SETTINGS_KEYS = [
292
+ 'model', 'model_num', 'inpainting_model',
293
+ 'vae', 'vae_num', 'latest_webui', 'latest_exstensions',
294
+ 'change_webui', 'detailed_download', 'controlnet',
295
+ 'controlnet_num', 'commit_hash', 'huggingface_token',
296
+ 'ngrok_token', 'zrok_token', 'commandline_arguments',
297
+ 'Model_url', 'Vae_url', 'LoRA_url', 'Embedding_url',
298
+ 'Extensions_url', 'custom_file_urls'
299
+ ]
300
+
301
+ def save_settings():
302
+ settings = {key: globals()[f"{key}_widget"].value for key in SETTINGS_KEYS}
303
+ with open(SETTINGS_FILE, 'w') as f:
304
+ json.dump(settings, f, indent=2)
305
+
306
+ def load_settings():
307
+ if os.path.exists(SETTINGS_FILE):
308
+ with open(SETTINGS_FILE, 'r') as f:
309
+ settings = json.load(f)
310
+ for key in SETTINGS_KEYS:
311
+ globals()[f"{key}_widget"].value = settings.get(key, "")
312
+
313
+ def hide_widgets():
314
+ widgets_list = [all_model_box, all_vae_box, all_additional_box, all_custom_box, save_button]
315
+ for widget in widgets_list:
316
+ widget.add_class("hide")
317
+ time.sleep(0.5)
318
+ widgets.Widget.close_all()
319
+
320
+ def save_data(button):
321
+ save_settings()
322
+ setup_webui(change_webui_widget.value)
323
+ hide_widgets()
324
+
325
+ load_settings()
326
+ save_button.on_click(save_data)
327
+