NagisaNao commited on
Commit
8ecaa8c
·
verified ·
1 Parent(s): 626d12c
files_cells/notebooks/en/auto-cleaner_en.ipynb ADDED
@@ -0,0 +1,368 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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.5 ~ | by ANXETY\n",
21
+ "\n",
22
+ "\n",
23
+ "\n",
24
+ "# =========================================================\n",
25
+ "import os\n",
26
+ "import sys\n",
27
+ "import time\n",
28
+ "import ipywidgets as widgets\n",
29
+ "from ipywidgets import Label, Button, VBox, HBox\n",
30
+ "from IPython.display import display, HTML\n",
31
+ "\n",
32
+ "\n",
33
+ "# ================= DETECT ENV =================\n",
34
+ "def detect_environment():\n",
35
+ " environments = {\n",
36
+ " 'COLAB_GPU': ('Google Colab', \"/content\"),\n",
37
+ " 'KAGGLE_URL_BASE': ('Kaggle', \"/kaggle/working/content\"),\n",
38
+ " 'SAGEMAKER_INTERNAL_IMAGE_URI': ('SageMaker Studio Lab', \"/home/studio-lab-user/content\")\n",
39
+ " }\n",
40
+ "\n",
41
+ " for env_var, (environment, path) in environments.items():\n",
42
+ " if env_var in os.environ:\n",
43
+ " return environment, path\n",
44
+ "\n",
45
+ " sys.exit(\"\\033[31mError: an unsupported runtime environment was detected.\\n\\033[34mSupported environments:\\033[0m Google Colab, Kaggle, Sagemaker Studio Lab\")\n",
46
+ "\n",
47
+ "env, root_path = detect_environment()\n",
48
+ "webui_path = f\"{root_path}/sdw\"\n",
49
+ "# ----------------------------------------------\n",
50
+ "\n",
51
+ "\n",
52
+ "directories = {\n",
53
+ " \"Images\": f\"{webui_path}/outputs\",\n",
54
+ " \"Models\": f\"{webui_path}/models/Stable-diffusion/\",\n",
55
+ " \"Vae\": f\"{webui_path}/models/VAE/\",\n",
56
+ " \"LoRa\": f\"{webui_path}/models/Lora/\",\n",
57
+ " \"ControlNet Models\": f\"{webui_path}/models/ControlNet/\"\n",
58
+ "}\n",
59
+ "\n",
60
+ "\n",
61
+ "# ==================== CSS ====================\n",
62
+ "CSS = \"\"\"\n",
63
+ "<style>\n",
64
+ "/* General Styles */\n",
65
+ "\n",
66
+ "hr {\n",
67
+ " border-color: grey;\n",
68
+ " background-color: grey;\n",
69
+ " opacity: 0.25;\n",
70
+ "}\n",
71
+ "\n",
72
+ ".instruction {\n",
73
+ " font-family: cursive;\n",
74
+ " font-size: 18px;\n",
75
+ " color: grey;\n",
76
+ " user-select: none;\n",
77
+ " cursor: default;\n",
78
+ "}\n",
79
+ "\n",
80
+ "\n",
81
+ "/* Container style */\n",
82
+ "\n",
83
+ ".container {\n",
84
+ " position: relative;\n",
85
+ " background-color: #232323;\n",
86
+ " width: 800px;\n",
87
+ " height: auto;\n",
88
+ " padding: 15px;\n",
89
+ " border-radius: 15px;\n",
90
+ " box-shadow: 0 0 50px rgba(0, 0, 0, 0.3);\n",
91
+ " margin-bottom: 5px;\n",
92
+ " overflow: visible;\n",
93
+ "}\n",
94
+ "\n",
95
+ ".container::before {\n",
96
+ " position: absolute;\n",
97
+ " top: 5px;\n",
98
+ " right: 10px;\n",
99
+ " content: \"AutoCleanerV3.5\";\n",
100
+ " font-weight: bold;\n",
101
+ " font-size: 24px;\n",
102
+ " color: rgba(0, 0, 0, 0.2);\n",
103
+ "}\n",
104
+ "\n",
105
+ ".container::after {\n",
106
+ " position: absolute;\n",
107
+ " top: 30px;\n",
108
+ " right: 10px;\n",
109
+ " content: \"ANXETY\";\n",
110
+ " font-weight: bold;\n",
111
+ " font-size: 18px;\n",
112
+ " color: rgba(0, 0, 0, 0.2);\n",
113
+ "}\n",
114
+ "\n",
115
+ ".custom-select-multiple select {\n",
116
+ " padding: 10px;\n",
117
+ " font-family: cursive;\n",
118
+ " border: 1px solid #262626;\n",
119
+ " border-radius: 10px;\n",
120
+ " color: white;\n",
121
+ " background-color: #1c1c1c;\n",
122
+ " box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);\n",
123
+ "}\n",
124
+ "\n",
125
+ ".output {\n",
126
+ " padding: 10px;\n",
127
+ " height: auto;\n",
128
+ " border: 1px solid #262626;\n",
129
+ " border-radius: 10px;\n",
130
+ " background-color: #1c1c1c;\n",
131
+ " box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);\n",
132
+ " width: auto;\n",
133
+ " box-sizing: border-box;\n",
134
+ "}\n",
135
+ "\n",
136
+ ".output_message {\n",
137
+ " font-family: cursive;\n",
138
+ " color: white !important;\n",
139
+ " font-size: 14px;\n",
140
+ " user-select: none;\n",
141
+ " cursor: default\n",
142
+ "}\n",
143
+ "\n",
144
+ "\n",
145
+ ".storage_info {\n",
146
+ " padding: 5px 20px;\n",
147
+ " height: auto;\n",
148
+ " border: 1px solid #262626;\n",
149
+ " border-radius: 10px;\n",
150
+ " background-color: #1c1c1c;\n",
151
+ " box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);\n",
152
+ " width: auto;\n",
153
+ " font-family: cursive;\n",
154
+ " color: #B2B2B2 !important;\n",
155
+ " font-size: 14px;\n",
156
+ " user-select: none;\n",
157
+ " cursor: default\n",
158
+ "}\n",
159
+ "\n",
160
+ "\n",
161
+ "/* Button and storage info layout */\n",
162
+ ".lower_information_panel {\n",
163
+ " display: flex;\n",
164
+ " align-items: center;\n",
165
+ " justify-content: space-between;\n",
166
+ "}\n",
167
+ "\n",
168
+ "\n",
169
+ "/* Button style */\n",
170
+ "\n",
171
+ ".button {\n",
172
+ " width: auto;\n",
173
+ " font-family: cursive;\n",
174
+ " color: white !important;\n",
175
+ " font-size: 14px;\n",
176
+ " font-weight: bold;\n",
177
+ " height: 35px;\n",
178
+ " border-radius: 15px;\n",
179
+ " background-image: radial-gradient(circle at top left, purple 10%, violet 90%);\n",
180
+ " background-size: 200% 200%;\n",
181
+ " background-position: left bottom;\n",
182
+ " transition: background 0.5s ease-in-out, transform 0.3s ease;\n",
183
+ "}\n",
184
+ "\n",
185
+ ".button:hover {\n",
186
+ " cursor: pointer;\n",
187
+ " background-size: 200% 200%;\n",
188
+ " background-position: right bottom;\n",
189
+ " transform: translateY(1px);\n",
190
+ "}\n",
191
+ "\n",
192
+ ".button_execute:hover {\n",
193
+ " background-image: radial-gradient(circle at top left, purple 10%, #93ac47 90%);\n",
194
+ "}\n",
195
+ "\n",
196
+ ".button_clear:hover {\n",
197
+ " background-image: radial-gradient(circle at top left, purple 10%, #fc3468 90%);\n",
198
+ "}\n",
199
+ "\n",
200
+ ".button_execute:active,\n",
201
+ ".button_clear:active {\n",
202
+ " filter: brightness(0.75);\n",
203
+ "}\n",
204
+ "\n",
205
+ ".jupyter-widgets.lm-Widget:focus {\n",
206
+ " outline: none;\n",
207
+ "}\n",
208
+ "\n",
209
+ "\n",
210
+ "/* Animation of elements */\n",
211
+ "\n",
212
+ "/* Emergence */\n",
213
+ ".container {\n",
214
+ " animation-name: slideInTopBlur;\n",
215
+ " animation-duration: 0.7s;\n",
216
+ " animation-fill-mode: forwards;\n",
217
+ "}\n",
218
+ "\n",
219
+ "@keyframes slideInTopBlur {\n",
220
+ " 0% {\n",
221
+ " transform: translate3d(0, 50%, 0) scale(0.85) rotate3d(1, 0, 0, -85deg);\n",
222
+ " filter: blur(5px) grayscale(1) brightness(0.5);\n",
223
+ " opacity: 0;\n",
224
+ " }\n",
225
+ " 100% {\n",
226
+ " transform: translate3d(0, 0, 0) scale(1) rotate3d(1, 0, 0, 0deg);\n",
227
+ " filter: blur(0) grayscale(0) brightness(1);\n",
228
+ " opacity: 1;\n",
229
+ " }\n",
230
+ "}\n",
231
+ "\n",
232
+ "/* Leaving */\n",
233
+ ".container.hide {\n",
234
+ " animation-name: slideOutTopBlur;\n",
235
+ " animation-duration: 0.5s;\n",
236
+ " animation-fill-mode: forwards;\n",
237
+ "}\n",
238
+ "\n",
239
+ "@keyframes slideOutTopBlur {\n",
240
+ " 0% {\n",
241
+ " transform: translate3d(0, 0, 0) scale(1);\n",
242
+ " filter: blur(0) grayscale(0) brightness(1);\n",
243
+ " opacity: 1;\n",
244
+ " }\n",
245
+ " 100% {\n",
246
+ " transform: translate3d(0, -100%, 0);\n",
247
+ " filter: blur(5px) grayscale(1) brightness(0);\n",
248
+ " opacity: 0;\n",
249
+ " }\n",
250
+ "}\n",
251
+ "</style>\n",
252
+ "\"\"\"\n",
253
+ "\n",
254
+ "display(HTML(CSS))\n",
255
+ "# ==================== CSS ====================\n",
256
+ "\n",
257
+ "\n",
258
+ "# ================ AutoCleaner function ================\n",
259
+ "def clean_directory(directory):\n",
260
+ " deleted_files = 0\n",
261
+ " for root, dirs, files in os.walk(directory):\n",
262
+ " for file in files:\n",
263
+ " if not file.endswith((\".txt\", \".yaml\")):\n",
264
+ " file_path = os.path.join(root, file)\n",
265
+ " os.remove(file_path)\n",
266
+ " deleted_files += 1\n",
267
+ "\n",
268
+ " return deleted_files\n",
269
+ "\n",
270
+ "\n",
271
+ "def get_word_variant(n, variants):\n",
272
+ " unit = abs(n) % 10\n",
273
+ " tens = abs(n) % 100\n",
274
+ "\n",
275
+ " if tens in range(11, 15):\n",
276
+ " return variants[2]\n",
277
+ " elif unit == 1:\n",
278
+ " return variants[0]\n",
279
+ " elif unit in range(2, 5):\n",
280
+ " return variants[1]\n",
281
+ " return variants[2]\n",
282
+ "\n",
283
+ "\n",
284
+ "def on_execute_button_press(button):\n",
285
+ " selected_cleaners = auto_cleaner_widget.value\n",
286
+ " deleted_files_dict = {}\n",
287
+ "\n",
288
+ " for option in selected_cleaners:\n",
289
+ " if option in directories:\n",
290
+ " deleted_files_dict[option] = clean_directory(directories[option])\n",
291
+ "\n",
292
+ " output.clear_output()\n",
293
+ "\n",
294
+ " with output:\n",
295
+ " for message in generate_messages(deleted_files_dict):\n",
296
+ " message_widget = HTML(f'<p class=\"output_message\">{message}</p>')\n",
297
+ " display(message_widget)\n",
298
+ "\n",
299
+ "\n",
300
+ "def on_clear_button_press(button):\n",
301
+ " container.add_class(\"hide\")\n",
302
+ " time.sleep(0.3)\n",
303
+ " widgets.Widget.close_all()\n",
304
+ "\n",
305
+ "\n",
306
+ "def generate_messages(deleted_files_dict):\n",
307
+ " messages = []\n",
308
+ " word_variants = {\n",
309
+ " \"Images\": [\"Image\", \"Images\", \"Images\"],\n",
310
+ " \"Models\": [\"Model\", \"Models\", \"Models\"],\n",
311
+ " \"Vae\": [\"VAE\", \"VAE\", \"VAE\"],\n",
312
+ " \"LoRa\": [\"LoRa\", \"LoRa\", \"LoRa\"],\n",
313
+ " \"ControlNet Models\": [\"ControlNet Model\", \"ControlNet Models\", \"ControlNet Models\"]\n",
314
+ " }\n",
315
+ " deleted_word_variants = [\"Deleted\", \"Deleted\", \"Deleted\"]\n",
316
+ "\n",
317
+ " for key, value in deleted_files_dict.items():\n",
318
+ " word_variant = word_variants.get(key, [\"\", \"\", \"\"])\n",
319
+ " deleted_word = get_word_variant(value, deleted_word_variants)\n",
320
+ " object_word = get_word_variant(value, word_variant)\n",
321
+ "\n",
322
+ " messages.append(f\"{deleted_word} {value} {object_word}\")\n",
323
+ "\n",
324
+ " return messages\n",
325
+ "# ================ AutoCleaner function ================\n",
326
+ "\n",
327
+ "\n",
328
+ "# --- storage memory ---\n",
329
+ "import psutil\n",
330
+ "directory = os.getcwd()\n",
331
+ "disk_space = psutil.disk_usage(directory)\n",
332
+ "total = disk_space.total / (1024 ** 3)\n",
333
+ "used = disk_space.used / (1024 ** 3)\n",
334
+ "free = disk_space.free / (1024 ** 3)\n",
335
+ "\n",
336
+ "\n",
337
+ "# UI Code\n",
338
+ "AutoCleaner_options = AutoCleaner_options = list(directories.keys())\n",
339
+ "instruction_label = widgets.HTML('''\n",
340
+ "<span class=\"instruction\">Use <span style=\"color: #B2B2B2;\">ctrl</span> or <span style=\"color: #B2B2B2;\">shift</span> for multiple selections.</span>\n",
341
+ "''')\n",
342
+ "auto_cleaner_widget = widgets.SelectMultiple(options=AutoCleaner_options, layout=widgets.Layout(width='100%')).add_class(\"custom-select-multiple\")\n",
343
+ "output = widgets.Output().add_class(\"output\")\n",
344
+ "# ---\n",
345
+ "execute_button = Button(description='Execute Cleaning').add_class(\"button_execute\").add_class(\"button\")\n",
346
+ "execute_button.on_click(on_execute_button_press)\n",
347
+ "clear_button = Button(description='Hide Widget').add_class(\"button_clear\").add_class(\"button\")\n",
348
+ "clear_button.on_click(on_clear_button_press)\n",
349
+ "# ---\n",
350
+ "storage_info = widgets.HTML(f'''\n",
351
+ "<div class=\"storage_info\">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",
352
+ "''')\n",
353
+ "# ---\n",
354
+ "buttons = widgets.HBox([execute_button, clear_button])\n",
355
+ "lower_information_panel = widgets.HBox([buttons, storage_info]).add_class(\"lower_information_panel\")\n",
356
+ "\n",
357
+ "container = VBox([instruction_label, widgets.HTML('<hr>'), auto_cleaner_widget, output, widgets.HTML('<hr>'), lower_information_panel]).add_class(\"container\")\n",
358
+ "\n",
359
+ "display(container)"
360
+ ],
361
+ "metadata": {
362
+ "id": "I22dFg7F2j3G"
363
+ },
364
+ "execution_count": null,
365
+ "outputs": []
366
+ }
367
+ ]
368
+ }
files_cells/notebooks/ru/auto-cleaner_ru.ipynb ADDED
@@ -0,0 +1,368 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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.5 ~ | by ANXETY\n",
21
+ "\n",
22
+ "\n",
23
+ "\n",
24
+ "# =========================================================\n",
25
+ "import os\n",
26
+ "import sys\n",
27
+ "import time\n",
28
+ "import ipywidgets as widgets\n",
29
+ "from ipywidgets import Label, Button, VBox, HBox\n",
30
+ "from IPython.display import display, HTML\n",
31
+ "\n",
32
+ "\n",
33
+ "# ================= DETECT ENV =================\n",
34
+ "def detect_environment():\n",
35
+ " environments = {\n",
36
+ " 'COLAB_GPU': ('Google Colab', \"/content\"),\n",
37
+ " 'KAGGLE_URL_BASE': ('Kaggle', \"/kaggle/working/content\"),\n",
38
+ " 'SAGEMAKER_INTERNAL_IMAGE_URI': ('SageMaker Studio Lab', \"/home/studio-lab-user/content\")\n",
39
+ " }\n",
40
+ "\n",
41
+ " for env_var, (environment, path) in environments.items():\n",
42
+ " if env_var in os.environ:\n",
43
+ " return environment, path\n",
44
+ "\n",
45
+ " sys.exit(\"\\033[31mError: an unsupported runtime environment was detected.\\n\\033[34mSupported environments:\\033[0m Google Colab, Kaggle, Sagemaker Studio Lab\")\n",
46
+ "\n",
47
+ "env, root_path = detect_environment()\n",
48
+ "webui_path = f\"{root_path}/sdw\"\n",
49
+ "# ----------------------------------------------\n",
50
+ "\n",
51
+ "\n",
52
+ "directories = {\n",
53
+ " \"Изображения\": f\"{webui_path}/outputs\",\n",
54
+ " \"Модели\": f\"{webui_path}/models/Stable-diffusion/\",\n",
55
+ " \"Vae\": f\"{webui_path}/models/VAE/\",\n",
56
+ " \"LoRa\": f\"{webui_path}/models/Lora/\",\n",
57
+ " \"ControlNet Модели\": f\"{webui_path}/models/ControlNet/\"\n",
58
+ "}\n",
59
+ "\n",
60
+ "\n",
61
+ "# ==================== CSS ====================\n",
62
+ "CSS = \"\"\"\n",
63
+ "<style>\n",
64
+ "/* General Styles */\n",
65
+ "\n",
66
+ "hr {\n",
67
+ " border-color: grey;\n",
68
+ " background-color: grey;\n",
69
+ " opacity: 0.25;\n",
70
+ "}\n",
71
+ "\n",
72
+ ".instruction {\n",
73
+ " font-family: cursive;\n",
74
+ " font-size: 18px;\n",
75
+ " color: grey;\n",
76
+ " user-select: none;\n",
77
+ " cursor: default;\n",
78
+ "}\n",
79
+ "\n",
80
+ "\n",
81
+ "/* Container style */\n",
82
+ "\n",
83
+ ".container {\n",
84
+ " position: relative;\n",
85
+ " background-color: #232323;\n",
86
+ " width: 800px;\n",
87
+ " height: auto;\n",
88
+ " padding: 15px;\n",
89
+ " border-radius: 15px;\n",
90
+ " box-shadow: 0 0 50px rgba(0, 0, 0, 0.3);\n",
91
+ " margin-bottom: 5px;\n",
92
+ " overflow: visible;\n",
93
+ "}\n",
94
+ "\n",
95
+ ".container::before {\n",
96
+ " position: absolute;\n",
97
+ " top: 5px;\n",
98
+ " right: 10px;\n",
99
+ " content: \"AutoCleanerV3.5\";\n",
100
+ " font-weight: bold;\n",
101
+ " font-size: 24px;\n",
102
+ " color: rgba(0, 0, 0, 0.2);\n",
103
+ "}\n",
104
+ "\n",
105
+ ".container::after {\n",
106
+ " position: absolute;\n",
107
+ " top: 30px;\n",
108
+ " right: 10px;\n",
109
+ " content: \"ANXETY\";\n",
110
+ " font-weight: bold;\n",
111
+ " font-size: 18px;\n",
112
+ " color: rgba(0, 0, 0, 0.2);\n",
113
+ "}\n",
114
+ "\n",
115
+ ".custom-select-multiple select {\n",
116
+ " padding: 10px;\n",
117
+ " font-family: cursive;\n",
118
+ " border: 1px solid #262626;\n",
119
+ " border-radius: 10px;\n",
120
+ " color: white;\n",
121
+ " background-color: #1c1c1c;\n",
122
+ " box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);\n",
123
+ "}\n",
124
+ "\n",
125
+ ".output {\n",
126
+ " padding: 10px;\n",
127
+ " height: auto;\n",
128
+ " border: 1px solid #262626;\n",
129
+ " border-radius: 10px;\n",
130
+ " background-color: #1c1c1c;\n",
131
+ " box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);\n",
132
+ " width: auto;\n",
133
+ " box-sizing: border-box;\n",
134
+ "}\n",
135
+ "\n",
136
+ ".output_message {\n",
137
+ " font-family: cursive;\n",
138
+ " color: white !important;\n",
139
+ " font-size: 14px;\n",
140
+ " user-select: none;\n",
141
+ " cursor: default\n",
142
+ "}\n",
143
+ "\n",
144
+ "\n",
145
+ ".storage_info {\n",
146
+ " padding: 5px 20px;\n",
147
+ " height: auto;\n",
148
+ " border: 1px solid #262626;\n",
149
+ " border-radius: 10px;\n",
150
+ " background-color: #1c1c1c;\n",
151
+ " box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);\n",
152
+ " width: auto;\n",
153
+ " font-family: cursive;\n",
154
+ " color: #B2B2B2 !important;\n",
155
+ " font-size: 14px;\n",
156
+ " user-select: none;\n",
157
+ " cursor: default\n",
158
+ "}\n",
159
+ "\n",
160
+ "\n",
161
+ "/* Button and storage info layout */\n",
162
+ ".lower_information_panel {\n",
163
+ " display: flex;\n",
164
+ " align-items: center;\n",
165
+ " justify-content: space-between;\n",
166
+ "}\n",
167
+ "\n",
168
+ "\n",
169
+ "/* Button style */\n",
170
+ "\n",
171
+ ".button {\n",
172
+ " width: auto;\n",
173
+ " font-family: cursive;\n",
174
+ " color: white !important;\n",
175
+ " font-size: 14px;\n",
176
+ " font-weight: bold;\n",
177
+ " height: 35px;\n",
178
+ " border-radius: 15px;\n",
179
+ " background-image: radial-gradient(circle at top left, purple 10%, violet 90%);\n",
180
+ " background-size: 200% 200%;\n",
181
+ " background-position: left bottom;\n",
182
+ " transition: background 0.5s ease-in-out, transform 0.3s ease;\n",
183
+ "}\n",
184
+ "\n",
185
+ ".button:hover {\n",
186
+ " cursor: pointer;\n",
187
+ " background-size: 200% 200%;\n",
188
+ " background-position: right bottom;\n",
189
+ " transform: translateY(1px);\n",
190
+ "}\n",
191
+ "\n",
192
+ ".button_execute:hover {\n",
193
+ " background-image: radial-gradient(circle at top left, purple 10%, #93ac47 90%);\n",
194
+ "}\n",
195
+ "\n",
196
+ ".button_clear:hover {\n",
197
+ " background-image: radial-gradient(circle at top left, purple 10%, #fc3468 90%);\n",
198
+ "}\n",
199
+ "\n",
200
+ ".button_execute:active,\n",
201
+ ".button_clear:active {\n",
202
+ " filter: brightness(0.75);\n",
203
+ "}\n",
204
+ "\n",
205
+ ".jupyter-widgets.lm-Widget:focus {\n",
206
+ " outline: none;\n",
207
+ "}\n",
208
+ "\n",
209
+ "\n",
210
+ "/* Animation of elements */\n",
211
+ "\n",
212
+ "/* Emergence */\n",
213
+ ".container {\n",
214
+ " animation-name: slideInTopBlur;\n",
215
+ " animation-duration: 0.7s;\n",
216
+ " animation-fill-mode: forwards;\n",
217
+ "}\n",
218
+ "\n",
219
+ "@keyframes slideInTopBlur {\n",
220
+ " 0% {\n",
221
+ " transform: translate3d(0, 50%, 0) scale(0.85) rotate3d(1, 0, 0, -85deg);\n",
222
+ " filter: blur(5px) grayscale(1) brightness(0.5);\n",
223
+ " opacity: 0;\n",
224
+ " }\n",
225
+ " 100% {\n",
226
+ " transform: translate3d(0, 0, 0) scale(1) rotate3d(1, 0, 0, 0deg);\n",
227
+ " filter: blur(0) grayscale(0) brightness(1);\n",
228
+ " opacity: 1;\n",
229
+ " }\n",
230
+ "}\n",
231
+ "\n",
232
+ "/* Leaving */\n",
233
+ ".container.hide {\n",
234
+ " animation-name: slideOutTopBlur;\n",
235
+ " animation-duration: 0.5s;\n",
236
+ " animation-fill-mode: forwards;\n",
237
+ "}\n",
238
+ "\n",
239
+ "@keyframes slideOutTopBlur {\n",
240
+ " 0% {\n",
241
+ " transform: translate3d(0, 0, 0) scale(1);\n",
242
+ " filter: blur(0) grayscale(0) brightness(1);\n",
243
+ " opacity: 1;\n",
244
+ " }\n",
245
+ " 100% {\n",
246
+ " transform: translate3d(0, -100%, 0);\n",
247
+ " filter: blur(5px) grayscale(1) brightness(0);\n",
248
+ " opacity: 0;\n",
249
+ " }\n",
250
+ "}\n",
251
+ "</style>\n",
252
+ "\"\"\"\n",
253
+ "\n",
254
+ "display(HTML(CSS))\n",
255
+ "# ==================== CSS ====================\n",
256
+ "\n",
257
+ "\n",
258
+ "# ================ AutoCleaner function ================\n",
259
+ "def clean_directory(directory):\n",
260
+ " deleted_files = 0\n",
261
+ " for root, dirs, files in os.walk(directory):\n",
262
+ " for file in files:\n",
263
+ " if not file.endswith((\".txt\", \".yaml\")):\n",
264
+ " file_path = os.path.join(root, file)\n",
265
+ " os.remove(file_path)\n",
266
+ " deleted_files += 1\n",
267
+ "\n",
268
+ " return deleted_files\n",
269
+ "\n",
270
+ "\n",
271
+ "def get_word_variant(n, variants):\n",
272
+ " unit = abs(n) % 10\n",
273
+ " tens = abs(n) % 100\n",
274
+ "\n",
275
+ " if tens in range(11, 15):\n",
276
+ " return variants[2]\n",
277
+ " elif unit == 1:\n",
278
+ " return variants[0]\n",
279
+ " elif unit in range(2, 5):\n",
280
+ " return variants[1]\n",
281
+ " return variants[2]\n",
282
+ "\n",
283
+ "\n",
284
+ "def on_execute_button_press(button):\n",
285
+ " selected_cleaners = auto_cleaner_widget.value\n",
286
+ " deleted_files_dict = {}\n",
287
+ "\n",
288
+ " for option in selected_cleaners:\n",
289
+ " if option in directories:\n",
290
+ " deleted_files_dict[option] = clean_directory(directories[option])\n",
291
+ "\n",
292
+ " output.clear_output()\n",
293
+ "\n",
294
+ " with output:\n",
295
+ " for message in generate_messages(deleted_files_dict):\n",
296
+ " message_widget = HTML(f'<p class=\"output_message\">{message}</p>')\n",
297
+ " display(message_widget)\n",
298
+ "\n",
299
+ "\n",
300
+ "def on_clear_button_press(button):\n",
301
+ " container.add_class(\"hide\")\n",
302
+ " time.sleep(0.3)\n",
303
+ " widgets.Widget.close_all()\n",
304
+ "\n",
305
+ "\n",
306
+ "def generate_messages(deleted_files_dict):\n",
307
+ " messages = []\n",
308
+ " word_variants = {\n",
309
+ " \"Изображения\": [\"Изображение\", \"Изображения\", \"Изображений\"],\n",
310
+ " \"Модели\": [\"Модель\", \"Модели\", \"Моделей\"],\n",
311
+ " \"Vae\": [\"VAE\", \"VAE\", \"VAE\"],\n",
312
+ " \"LoRa\": [\"LoRa\", \"LoRa\", \"LoRa\"],\n",
313
+ " \"ControlNet Модели\": [\"ControlNet Модель\", \"ControlNet Модели\", \"ControlNet Моделей\"]\n",
314
+ " }\n",
315
+ " deleted_word_variants = [\"Удалена\", \"Удалены\", \"Удалено\"]\n",
316
+ "\n",
317
+ " for key, value in deleted_files_dict.items():\n",
318
+ " word_variant = word_variants.get(key, [\"\", \"\", \"\"])\n",
319
+ " deleted_word = get_word_variant(value, deleted_word_variants)\n",
320
+ " object_word = get_word_variant(value, word_variant)\n",
321
+ "\n",
322
+ " messages.append(f\"{deleted_word} {value} {object_word}\")\n",
323
+ "\n",
324
+ " return messages\n",
325
+ "# ================ AutoCleaner function ================\n",
326
+ "\n",
327
+ "\n",
328
+ "# --- storage memory ---\n",
329
+ "import psutil\n",
330
+ "directory = os.getcwd()\n",
331
+ "disk_space = psutil.disk_usage(directory)\n",
332
+ "total = disk_space.total / (1024 ** 3)\n",
333
+ "used = disk_space.used / (1024 ** 3)\n",
334
+ "free = disk_space.free / (1024 ** 3)\n",
335
+ "\n",
336
+ "\n",
337
+ "# UI Code\n",
338
+ "AutoCleaner_options = AutoCleaner_options = list(directories.keys())\n",
339
+ "instruction_label = widgets.HTML('''\n",
340
+ "<span class=\"instruction\">Используйте <span style=\"color: #B2B2B2;\">ctrl</span> или <span style=\"color: #B2B2B2;\">shift</span> для множественного выбора.</span>\n",
341
+ "''')\n",
342
+ "auto_cleaner_widget = widgets.SelectMultiple(options=AutoCleaner_options, layout=widgets.Layout(width='100%')).add_class(\"custom-select-multiple\")\n",
343
+ "output = widgets.Output().add_class(\"output\")\n",
344
+ "# ---\n",
345
+ "execute_button = Button(description='Выполнить Очистку').add_class(\"button_execute\").add_class(\"button\")\n",
346
+ "execute_button.on_click(on_execute_button_press)\n",
347
+ "clear_button = Button(description='Скрыть Виджет').add_class(\"button_clear\").add_class(\"button\")\n",
348
+ "clear_button.on_click(on_clear_button_press)\n",
349
+ "# ---\n",
350
+ "storage_info = widgets.HTML(f'''\n",
351
+ "<div class=\"storage_info\">Всего: {total:.2f} GB <span style=\"color: #555\">|</span> Используется: {used:.2f} GB <span style=\"color: #555\">|</span> Свободно: {free:.2f} GB</div>\n",
352
+ "''')\n",
353
+ "# ---\n",
354
+ "buttons = widgets.HBox([execute_button, clear_button])\n",
355
+ "lower_information_panel = widgets.HBox([buttons, storage_info]).add_class(\"lower_information_panel\")\n",
356
+ "\n",
357
+ "container = VBox([instruction_label, widgets.HTML('<hr>'), auto_cleaner_widget, output, widgets.HTML('<hr>'), lower_information_panel]).add_class(\"container\")\n",
358
+ "\n",
359
+ "display(container)"
360
+ ],
361
+ "metadata": {
362
+ "id": "I22dFg7F2j3G"
363
+ },
364
+ "execution_count": null,
365
+ "outputs": []
366
+ }
367
+ ]
368
+ }
files_cells/python/en/auto-cleaner_en.py ADDED
@@ -0,0 +1,347 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ # coding: utf-8
3
+
4
+ # In[ ]:
5
+
6
+
7
+ # ~ AutoCleaner V3.5 ~ | by ANXETY
8
+
9
+
10
+
11
+ # =========================================================
12
+ import os
13
+ import sys
14
+ import time
15
+ import ipywidgets as widgets
16
+ from ipywidgets import Label, Button, VBox, HBox
17
+ from IPython.display import display, HTML
18
+
19
+
20
+ # ================= DETECT ENV =================
21
+ def detect_environment():
22
+ environments = {
23
+ 'COLAB_GPU': ('Google Colab', "/content"),
24
+ 'KAGGLE_URL_BASE': ('Kaggle', "/kaggle/working/content"),
25
+ 'SAGEMAKER_INTERNAL_IMAGE_URI': ('SageMaker Studio Lab', "/home/studio-lab-user/content")
26
+ }
27
+
28
+ for env_var, (environment, path) in environments.items():
29
+ if env_var in os.environ:
30
+ return environment, path
31
+
32
+ sys.exit("\033[31mError: an unsupported runtime environment was detected.\n\033[34mSupported environments:\033[0m Google Colab, Kaggle, Sagemaker Studio Lab")
33
+
34
+ env, root_path = detect_environment()
35
+ webui_path = f"{root_path}/sdw"
36
+ # ----------------------------------------------
37
+
38
+
39
+ directories = {
40
+ "Images": f"{webui_path}/outputs",
41
+ "Models": f"{webui_path}/models/Stable-diffusion/",
42
+ "Vae": f"{webui_path}/models/VAE/",
43
+ "LoRa": f"{webui_path}/models/Lora/",
44
+ "ControlNet Models": f"{webui_path}/models/ControlNet/"
45
+ }
46
+
47
+
48
+ # ==================== CSS ====================
49
+ CSS = """
50
+ <style>
51
+ /* General Styles */
52
+
53
+ hr {
54
+ border-color: grey;
55
+ background-color: grey;
56
+ opacity: 0.25;
57
+ }
58
+
59
+ .instruction {
60
+ font-family: cursive;
61
+ font-size: 18px;
62
+ color: grey;
63
+ user-select: none;
64
+ cursor: default;
65
+ }
66
+
67
+
68
+ /* Container style */
69
+
70
+ .container {
71
+ position: relative;
72
+ background-color: #232323;
73
+ width: 800px;
74
+ height: auto;
75
+ padding: 15px;
76
+ border-radius: 15px;
77
+ box-shadow: 0 0 50px rgba(0, 0, 0, 0.3);
78
+ margin-bottom: 5px;
79
+ overflow: visible;
80
+ }
81
+
82
+ .container::before {
83
+ position: absolute;
84
+ top: 5px;
85
+ right: 10px;
86
+ content: "AutoCleanerV3.5";
87
+ font-weight: bold;
88
+ font-size: 24px;
89
+ color: rgba(0, 0, 0, 0.2);
90
+ }
91
+
92
+ .container::after {
93
+ position: absolute;
94
+ top: 30px;
95
+ right: 10px;
96
+ content: "ANXETY";
97
+ font-weight: bold;
98
+ font-size: 18px;
99
+ color: rgba(0, 0, 0, 0.2);
100
+ }
101
+
102
+ .custom-select-multiple select {
103
+ padding: 10px;
104
+ font-family: cursive;
105
+ border: 1px solid #262626;
106
+ border-radius: 10px;
107
+ color: white;
108
+ background-color: #1c1c1c;
109
+ box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);
110
+ }
111
+
112
+ .output {
113
+ padding: 10px;
114
+ height: auto;
115
+ border: 1px solid #262626;
116
+ border-radius: 10px;
117
+ background-color: #1c1c1c;
118
+ box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);
119
+ width: auto;
120
+ box-sizing: border-box;
121
+ }
122
+
123
+ .output_message {
124
+ font-family: cursive;
125
+ color: white !important;
126
+ font-size: 14px;
127
+ user-select: none;
128
+ cursor: default
129
+ }
130
+
131
+
132
+ .storage_info {
133
+ padding: 5px 20px;
134
+ height: auto;
135
+ border: 1px solid #262626;
136
+ border-radius: 10px;
137
+ background-color: #1c1c1c;
138
+ box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);
139
+ width: auto;
140
+ font-family: cursive;
141
+ color: #B2B2B2 !important;
142
+ font-size: 14px;
143
+ user-select: none;
144
+ cursor: default
145
+ }
146
+
147
+
148
+ /* Button and storage info layout */
149
+ .lower_information_panel {
150
+ display: flex;
151
+ align-items: center;
152
+ justify-content: space-between;
153
+ }
154
+
155
+
156
+ /* Button style */
157
+
158
+ .button {
159
+ width: auto;
160
+ font-family: cursive;
161
+ color: white !important;
162
+ font-size: 14px;
163
+ font-weight: bold;
164
+ height: 35px;
165
+ border-radius: 15px;
166
+ background-image: radial-gradient(circle at top left, purple 10%, violet 90%);
167
+ background-size: 200% 200%;
168
+ background-position: left bottom;
169
+ transition: background 0.5s ease-in-out, transform 0.3s ease;
170
+ }
171
+
172
+ .button:hover {
173
+ cursor: pointer;
174
+ background-size: 200% 200%;
175
+ background-position: right bottom;
176
+ transform: translateY(1px);
177
+ }
178
+
179
+ .button_execute:hover {
180
+ background-image: radial-gradient(circle at top left, purple 10%, #93ac47 90%);
181
+ }
182
+
183
+ .button_clear:hover {
184
+ background-image: radial-gradient(circle at top left, purple 10%, #fc3468 90%);
185
+ }
186
+
187
+ .button_execute:active,
188
+ .button_clear:active {
189
+ filter: brightness(0.75);
190
+ }
191
+
192
+ .jupyter-widgets.lm-Widget:focus {
193
+ outline: none;
194
+ }
195
+
196
+
197
+ /* Animation of elements */
198
+
199
+ /* Emergence */
200
+ .container {
201
+ animation-name: slideInTopBlur;
202
+ animation-duration: 0.7s;
203
+ animation-fill-mode: forwards;
204
+ }
205
+
206
+ @keyframes slideInTopBlur {
207
+ 0% {
208
+ transform: translate3d(0, 50%, 0) scale(0.85) rotate3d(1, 0, 0, -85deg);
209
+ filter: blur(5px) grayscale(1) brightness(0.5);
210
+ opacity: 0;
211
+ }
212
+ 100% {
213
+ transform: translate3d(0, 0, 0) scale(1) rotate3d(1, 0, 0, 0deg);
214
+ filter: blur(0) grayscale(0) brightness(1);
215
+ opacity: 1;
216
+ }
217
+ }
218
+
219
+ /* Leaving */
220
+ .container.hide {
221
+ animation-name: slideOutTopBlur;
222
+ animation-duration: 0.5s;
223
+ animation-fill-mode: forwards;
224
+ }
225
+
226
+ @keyframes slideOutTopBlur {
227
+ 0% {
228
+ transform: translate3d(0, 0, 0) scale(1);
229
+ filter: blur(0) grayscale(0) brightness(1);
230
+ opacity: 1;
231
+ }
232
+ 100% {
233
+ transform: translate3d(0, -100%, 0);
234
+ filter: blur(5px) grayscale(1) brightness(0);
235
+ opacity: 0;
236
+ }
237
+ }
238
+ </style>
239
+ """
240
+
241
+ display(HTML(CSS))
242
+ # ==================== CSS ====================
243
+
244
+
245
+ # ================ AutoCleaner function ================
246
+ def clean_directory(directory):
247
+ deleted_files = 0
248
+ for root, dirs, files in os.walk(directory):
249
+ for file in files:
250
+ if not file.endswith((".txt", ".yaml")):
251
+ file_path = os.path.join(root, file)
252
+ os.remove(file_path)
253
+ deleted_files += 1
254
+
255
+ return deleted_files
256
+
257
+
258
+ def get_word_variant(n, variants):
259
+ unit = abs(n) % 10
260
+ tens = abs(n) % 100
261
+
262
+ if tens in range(11, 15):
263
+ return variants[2]
264
+ elif unit == 1:
265
+ return variants[0]
266
+ elif unit in range(2, 5):
267
+ return variants[1]
268
+ return variants[2]
269
+
270
+
271
+ def on_execute_button_press(button):
272
+ selected_cleaners = auto_cleaner_widget.value
273
+ deleted_files_dict = {}
274
+
275
+ for option in selected_cleaners:
276
+ if option in directories:
277
+ deleted_files_dict[option] = clean_directory(directories[option])
278
+
279
+ output.clear_output()
280
+
281
+ with output:
282
+ for message in generate_messages(deleted_files_dict):
283
+ message_widget = HTML(f'<p class="output_message">{message}</p>')
284
+ display(message_widget)
285
+
286
+
287
+ def on_clear_button_press(button):
288
+ container.add_class("hide")
289
+ time.sleep(0.3)
290
+ widgets.Widget.close_all()
291
+
292
+
293
+ def generate_messages(deleted_files_dict):
294
+ messages = []
295
+ word_variants = {
296
+ "Images": ["Image", "Images", "Images"],
297
+ "Models": ["Model", "Models", "Models"],
298
+ "Vae": ["VAE", "VAE", "VAE"],
299
+ "LoRa": ["LoRa", "LoRa", "LoRa"],
300
+ "ControlNet Models": ["ControlNet Model", "ControlNet Models", "ControlNet Models"]
301
+ }
302
+ deleted_word_variants = ["Deleted", "Deleted", "Deleted"]
303
+
304
+ for key, value in deleted_files_dict.items():
305
+ word_variant = word_variants.get(key, ["", "", ""])
306
+ deleted_word = get_word_variant(value, deleted_word_variants)
307
+ object_word = get_word_variant(value, word_variant)
308
+
309
+ messages.append(f"{deleted_word} {value} {object_word}")
310
+
311
+ return messages
312
+ # ================ AutoCleaner function ================
313
+
314
+
315
+ # --- storage memory ---
316
+ import psutil
317
+ directory = os.getcwd()
318
+ disk_space = psutil.disk_usage(directory)
319
+ total = disk_space.total / (1024 ** 3)
320
+ used = disk_space.used / (1024 ** 3)
321
+ free = disk_space.free / (1024 ** 3)
322
+
323
+
324
+ # UI Code
325
+ AutoCleaner_options = AutoCleaner_options = list(directories.keys())
326
+ instruction_label = widgets.HTML('''
327
+ <span class="instruction">Use <span style="color: #B2B2B2;">ctrl</span> or <span style="color: #B2B2B2;">shift</span> for multiple selections.</span>
328
+ ''')
329
+ auto_cleaner_widget = widgets.SelectMultiple(options=AutoCleaner_options, layout=widgets.Layout(width='100%')).add_class("custom-select-multiple")
330
+ output = widgets.Output().add_class("output")
331
+ # ---
332
+ execute_button = Button(description='Execute Cleaning').add_class("button_execute").add_class("button")
333
+ execute_button.on_click(on_execute_button_press)
334
+ clear_button = Button(description='Hide Widget').add_class("button_clear").add_class("button")
335
+ clear_button.on_click(on_clear_button_press)
336
+ # ---
337
+ storage_info = widgets.HTML(f'''
338
+ <div class="storage_info">Total storage: {total:.2f} GB <span style="color: #555">|</span> Used: {used:.2f} GB <span style="color: #555">|</span> Free: {free:.2f} GB</div>
339
+ ''')
340
+ # ---
341
+ buttons = widgets.HBox([execute_button, clear_button])
342
+ lower_information_panel = widgets.HBox([buttons, storage_info]).add_class("lower_information_panel")
343
+
344
+ container = VBox([instruction_label, widgets.HTML('<hr>'), auto_cleaner_widget, output, widgets.HTML('<hr>'), lower_information_panel]).add_class("container")
345
+
346
+ display(container)
347
+
files_cells/python/ru/auto-cleaner_ru.py ADDED
@@ -0,0 +1,347 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ # coding: utf-8
3
+
4
+ # In[ ]:
5
+
6
+
7
+ # ~ AutoCleaner V3.5 ~ | by ANXETY
8
+
9
+
10
+
11
+ # =========================================================
12
+ import os
13
+ import sys
14
+ import time
15
+ import ipywidgets as widgets
16
+ from ipywidgets import Label, Button, VBox, HBox
17
+ from IPython.display import display, HTML
18
+
19
+
20
+ # ================= DETECT ENV =================
21
+ def detect_environment():
22
+ environments = {
23
+ 'COLAB_GPU': ('Google Colab', "/content"),
24
+ 'KAGGLE_URL_BASE': ('Kaggle', "/kaggle/working/content"),
25
+ 'SAGEMAKER_INTERNAL_IMAGE_URI': ('SageMaker Studio Lab', "/home/studio-lab-user/content")
26
+ }
27
+
28
+ for env_var, (environment, path) in environments.items():
29
+ if env_var in os.environ:
30
+ return environment, path
31
+
32
+ sys.exit("\033[31mError: an unsupported runtime environment was detected.\n\033[34mSupported environments:\033[0m Google Colab, Kaggle, Sagemaker Studio Lab")
33
+
34
+ env, root_path = detect_environment()
35
+ webui_path = f"{root_path}/sdw"
36
+ # ----------------------------------------------
37
+
38
+
39
+ directories = {
40
+ "Изображения": f"{webui_path}/outputs",
41
+ "Модели": f"{webui_path}/models/Stable-diffusion/",
42
+ "Vae": f"{webui_path}/models/VAE/",
43
+ "LoRa": f"{webui_path}/models/Lora/",
44
+ "ControlNet Модели": f"{webui_path}/models/ControlNet/"
45
+ }
46
+
47
+
48
+ # ==================== CSS ====================
49
+ CSS = """
50
+ <style>
51
+ /* General Styles */
52
+
53
+ hr {
54
+ border-color: grey;
55
+ background-color: grey;
56
+ opacity: 0.25;
57
+ }
58
+
59
+ .instruction {
60
+ font-family: cursive;
61
+ font-size: 18px;
62
+ color: grey;
63
+ user-select: none;
64
+ cursor: default;
65
+ }
66
+
67
+
68
+ /* Container style */
69
+
70
+ .container {
71
+ position: relative;
72
+ background-color: #232323;
73
+ width: 800px;
74
+ height: auto;
75
+ padding: 15px;
76
+ border-radius: 15px;
77
+ box-shadow: 0 0 50px rgba(0, 0, 0, 0.3);
78
+ margin-bottom: 5px;
79
+ overflow: visible;
80
+ }
81
+
82
+ .container::before {
83
+ position: absolute;
84
+ top: 5px;
85
+ right: 10px;
86
+ content: "AutoCleanerV3.5";
87
+ font-weight: bold;
88
+ font-size: 24px;
89
+ color: rgba(0, 0, 0, 0.2);
90
+ }
91
+
92
+ .container::after {
93
+ position: absolute;
94
+ top: 30px;
95
+ right: 10px;
96
+ content: "ANXETY";
97
+ font-weight: bold;
98
+ font-size: 18px;
99
+ color: rgba(0, 0, 0, 0.2);
100
+ }
101
+
102
+ .custom-select-multiple select {
103
+ padding: 10px;
104
+ font-family: cursive;
105
+ border: 1px solid #262626;
106
+ border-radius: 10px;
107
+ color: white;
108
+ background-color: #1c1c1c;
109
+ box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);
110
+ }
111
+
112
+ .output {
113
+ padding: 10px;
114
+ height: auto;
115
+ border: 1px solid #262626;
116
+ border-radius: 10px;
117
+ background-color: #1c1c1c;
118
+ box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);
119
+ width: auto;
120
+ box-sizing: border-box;
121
+ }
122
+
123
+ .output_message {
124
+ font-family: cursive;
125
+ color: white !important;
126
+ font-size: 14px;
127
+ user-select: none;
128
+ cursor: default
129
+ }
130
+
131
+
132
+ .storage_info {
133
+ padding: 5px 20px;
134
+ height: auto;
135
+ border: 1px solid #262626;
136
+ border-radius: 10px;
137
+ background-color: #1c1c1c;
138
+ box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);
139
+ width: auto;
140
+ font-family: cursive;
141
+ color: #B2B2B2 !important;
142
+ font-size: 14px;
143
+ user-select: none;
144
+ cursor: default
145
+ }
146
+
147
+
148
+ /* Button and storage info layout */
149
+ .lower_information_panel {
150
+ display: flex;
151
+ align-items: center;
152
+ justify-content: space-between;
153
+ }
154
+
155
+
156
+ /* Button style */
157
+
158
+ .button {
159
+ width: auto;
160
+ font-family: cursive;
161
+ color: white !important;
162
+ font-size: 14px;
163
+ font-weight: bold;
164
+ height: 35px;
165
+ border-radius: 15px;
166
+ background-image: radial-gradient(circle at top left, purple 10%, violet 90%);
167
+ background-size: 200% 200%;
168
+ background-position: left bottom;
169
+ transition: background 0.5s ease-in-out, transform 0.3s ease;
170
+ }
171
+
172
+ .button:hover {
173
+ cursor: pointer;
174
+ background-size: 200% 200%;
175
+ background-position: right bottom;
176
+ transform: translateY(1px);
177
+ }
178
+
179
+ .button_execute:hover {
180
+ background-image: radial-gradient(circle at top left, purple 10%, #93ac47 90%);
181
+ }
182
+
183
+ .button_clear:hover {
184
+ background-image: radial-gradient(circle at top left, purple 10%, #fc3468 90%);
185
+ }
186
+
187
+ .button_execute:active,
188
+ .button_clear:active {
189
+ filter: brightness(0.75);
190
+ }
191
+
192
+ .jupyter-widgets.lm-Widget:focus {
193
+ outline: none;
194
+ }
195
+
196
+
197
+ /* Animation of elements */
198
+
199
+ /* Emergence */
200
+ .container {
201
+ animation-name: slideInTopBlur;
202
+ animation-duration: 0.7s;
203
+ animation-fill-mode: forwards;
204
+ }
205
+
206
+ @keyframes slideInTopBlur {
207
+ 0% {
208
+ transform: translate3d(0, 50%, 0) scale(0.85) rotate3d(1, 0, 0, -85deg);
209
+ filter: blur(5px) grayscale(1) brightness(0.5);
210
+ opacity: 0;
211
+ }
212
+ 100% {
213
+ transform: translate3d(0, 0, 0) scale(1) rotate3d(1, 0, 0, 0deg);
214
+ filter: blur(0) grayscale(0) brightness(1);
215
+ opacity: 1;
216
+ }
217
+ }
218
+
219
+ /* Leaving */
220
+ .container.hide {
221
+ animation-name: slideOutTopBlur;
222
+ animation-duration: 0.5s;
223
+ animation-fill-mode: forwards;
224
+ }
225
+
226
+ @keyframes slideOutTopBlur {
227
+ 0% {
228
+ transform: translate3d(0, 0, 0) scale(1);
229
+ filter: blur(0) grayscale(0) brightness(1);
230
+ opacity: 1;
231
+ }
232
+ 100% {
233
+ transform: translate3d(0, -100%, 0);
234
+ filter: blur(5px) grayscale(1) brightness(0);
235
+ opacity: 0;
236
+ }
237
+ }
238
+ </style>
239
+ """
240
+
241
+ display(HTML(CSS))
242
+ # ==================== CSS ====================
243
+
244
+
245
+ # ================ AutoCleaner function ================
246
+ def clean_directory(directory):
247
+ deleted_files = 0
248
+ for root, dirs, files in os.walk(directory):
249
+ for file in files:
250
+ if not file.endswith((".txt", ".yaml")):
251
+ file_path = os.path.join(root, file)
252
+ os.remove(file_path)
253
+ deleted_files += 1
254
+
255
+ return deleted_files
256
+
257
+
258
+ def get_word_variant(n, variants):
259
+ unit = abs(n) % 10
260
+ tens = abs(n) % 100
261
+
262
+ if tens in range(11, 15):
263
+ return variants[2]
264
+ elif unit == 1:
265
+ return variants[0]
266
+ elif unit in range(2, 5):
267
+ return variants[1]
268
+ return variants[2]
269
+
270
+
271
+ def on_execute_button_press(button):
272
+ selected_cleaners = auto_cleaner_widget.value
273
+ deleted_files_dict = {}
274
+
275
+ for option in selected_cleaners:
276
+ if option in directories:
277
+ deleted_files_dict[option] = clean_directory(directories[option])
278
+
279
+ output.clear_output()
280
+
281
+ with output:
282
+ for message in generate_messages(deleted_files_dict):
283
+ message_widget = HTML(f'<p class="output_message">{message}</p>')
284
+ display(message_widget)
285
+
286
+
287
+ def on_clear_button_press(button):
288
+ container.add_class("hide")
289
+ time.sleep(0.3)
290
+ widgets.Widget.close_all()
291
+
292
+
293
+ def generate_messages(deleted_files_dict):
294
+ messages = []
295
+ word_variants = {
296
+ "Изображения": ["Изображение", "Изображения", "Изображений"],
297
+ "Модели": ["Модель", "Модели", "Моделей"],
298
+ "Vae": ["VAE", "VAE", "VAE"],
299
+ "LoRa": ["LoRa", "LoRa", "LoRa"],
300
+ "ControlNet Модели": ["ControlNet Модель", "ControlNet Модели", "ControlNet Моделей"]
301
+ }
302
+ deleted_word_variants = ["Удалена", "Удалены", "Удалено"]
303
+
304
+ for key, value in deleted_files_dict.items():
305
+ word_variant = word_variants.get(key, ["", "", ""])
306
+ deleted_word = get_word_variant(value, deleted_word_variants)
307
+ object_word = get_word_variant(value, word_variant)
308
+
309
+ messages.append(f"{deleted_word} {value} {object_word}")
310
+
311
+ return messages
312
+ # ================ AutoCleaner function ================
313
+
314
+
315
+ # --- storage memory ---
316
+ import psutil
317
+ directory = os.getcwd()
318
+ disk_space = psutil.disk_usage(directory)
319
+ total = disk_space.total / (1024 ** 3)
320
+ used = disk_space.used / (1024 ** 3)
321
+ free = disk_space.free / (1024 ** 3)
322
+
323
+
324
+ # UI Code
325
+ AutoCleaner_options = AutoCleaner_options = list(directories.keys())
326
+ instruction_label = widgets.HTML('''
327
+ <span class="instruction">Используйте <span style="color: #B2B2B2;">ctrl</span> или <span style="color: #B2B2B2;">shift</span> для множественного выбора.</span>
328
+ ''')
329
+ auto_cleaner_widget = widgets.SelectMultiple(options=AutoCleaner_options, layout=widgets.Layout(width='100%')).add_class("custom-select-multiple")
330
+ output = widgets.Output().add_class("output")
331
+ # ---
332
+ execute_button = Button(description='Выполнить Очистку').add_class("button_execute").add_class("button")
333
+ execute_button.on_click(on_execute_button_press)
334
+ clear_button = Button(description='Скрыть Виджет').add_class("button_clear").add_class("button")
335
+ clear_button.on_click(on_clear_button_press)
336
+ # ---
337
+ storage_info = widgets.HTML(f'''
338
+ <div class="storage_info">Всего: {total:.2f} GB <span style="color: #555">|</span> Используется: {used:.2f} GB <span style="color: #555">|</span> Свободно: {free:.2f} GB</div>
339
+ ''')
340
+ # ---
341
+ buttons = widgets.HBox([execute_button, clear_button])
342
+ lower_information_panel = widgets.HBox([buttons, storage_info]).add_class("lower_information_panel")
343
+
344
+ container = VBox([instruction_label, widgets.HTML('<hr>'), auto_cleaner_widget, output, widgets.HTML('<hr>'), lower_information_panel]).add_class("container")
345
+
346
+ display(container)
347
+