Son aktivite 1760165031

urocibg bu gisti düzenledi 1760165031. Düzenlemeye git

1 file changed, 331 insertions

desktop_organizer.py(dosya oluşturuldu)

@@ -0,0 +1,331 @@
1 + import os
2 + import shutil
3 + import tkinter as tk
4 + from tkinter import ttk, messagebox, scrolledtext
5 + from pathlib import Path
6 + import threading
7 + from datetime import datetime
8 +
9 + class DesktopOrganizerGUI:
10 + def __init__(self, root):
11 + self.root = root
12 + self.root.title("Desktop Organizer - Windows 11")
13 + self.root.geometry("700x600")
14 + self.root.resizable(False, False)
15 +
16 + # Стилизация
17 + style = ttk.Style()
18 + style.theme_use('clam')
19 +
20 + # Определяне на Desktop пътя
21 + self.desktop_path = Path.home() / "Desktop"
22 +
23 + # Категории за файлове
24 + self.categories = {
25 + "Документи": [".pdf", ".doc", ".docx", ".txt", ".rtf", ".odt", ".xls", ".xlsx", ".ppt", ".pptx"],
26 + "Изображения": [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".svg", ".ico", ".webp", ".tiff"],
27 + "Видео": [".mp4", ".avi", ".mkv", ".mov", ".wmv", ".flv", ".webm"],
28 + "Музика": [".mp3", ".wav", ".flac", ".aac", ".ogg", ".wma", ".m4a"],
29 + "Архиви": [".zip", ".rar", ".7z", ".tar", ".gz", ".bz2"],
30 + "Програми": [".exe", ".msi", ".bat", ".cmd"],
31 + "Код": [".py", ".js", ".html", ".css", ".cpp", ".java", ".c", ".h", ".json", ".xml"],
32 + "Други": []
33 + }
34 +
35 + # Системни файлове и папки за игнориране
36 + self.system_items = ["desktop.ini", "Thumbs.db", "$RECYCLE.BIN"]
37 +
38 + self.create_widgets()
39 +
40 + def create_widgets(self):
41 + # Заглавие
42 + title_frame = tk.Frame(self.root, bg="#0078D4", height=80)
43 + title_frame.pack(fill="x")
44 + title_frame.pack_propagate(False)
45 +
46 + title_label = tk.Label(
47 + title_frame,
48 + text="🧹 Desktop Organizer",
49 + font=("Segoe UI", 20, "bold"),
50 + bg="#0078D4",
51 + fg="white"
52 + )
53 + title_label.pack(pady=20)
54 +
55 + # Основна рамка
56 + main_frame = tk.Frame(self.root, padx=20, pady=20)
57 + main_frame.pack(fill="both", expand=True)
58 +
59 + # Информация
60 + info_label = tk.Label(
61 + main_frame,
62 + text=f"📂 Desktop път: {self.desktop_path}",
63 + font=("Segoe UI", 10),
64 + justify="left",
65 + anchor="w"
66 + )
67 + info_label.pack(fill="x", pady=(0, 10))
68 +
69 + # Настройки рамка
70 + settings_frame = tk.LabelFrame(
71 + main_frame,
72 + text="⚙️ Настройки",
73 + font=("Segoe UI", 11, "bold"),
74 + padx=15,
75 + pady=15
76 + )
77 + settings_frame.pack(fill="x", pady=(0, 15))
78 +
79 + self.keep_shortcuts = tk.BooleanVar(value=True)
80 + tk.Checkbutton(
81 + settings_frame,
82 + text="✓ Запази всички пряки пътища (.lnk)",
83 + variable=self.keep_shortcuts,
84 + font=("Segoe UI", 10)
85 + ).pack(anchor="w", pady=5)
86 +
87 + self.keep_folders = tk.BooleanVar(value=True)
88 + tk.Checkbutton(
89 + settings_frame,
90 + text="✓ Запази съществуващите папки на мястото им",
91 + variable=self.keep_folders,
92 + font=("Segoe UI", 10)
93 + ).pack(anchor="w", pady=5)
94 +
95 + self.main_folder_name = tk.StringVar(value="Организиран Desktop")
96 + folder_frame = tk.Frame(settings_frame)
97 + folder_frame.pack(fill="x", pady=5)
98 + tk.Label(
99 + folder_frame,
100 + text="📁 Име на главната папка:",
101 + font=("Segoe UI", 10)
102 + ).pack(side="left")
103 + tk.Entry(
104 + folder_frame,
105 + textvariable=self.main_folder_name,
106 + font=("Segoe UI", 10),
107 + width=30
108 + ).pack(side="left", padx=10)
109 +
110 + # Бутони
111 + button_frame = tk.Frame(main_frame)
112 + button_frame.pack(fill="x", pady=(0, 15))
113 +
114 + self.preview_btn = tk.Button(
115 + button_frame,
116 + text="👁️ Преглед",
117 + font=("Segoe UI", 11, "bold"),
118 + bg="#0078D4",
119 + fg="white",
120 + padx=20,
121 + pady=10,
122 + cursor="hand2",
123 + command=self.preview_organization
124 + )
125 + self.preview_btn.pack(side="left", padx=(0, 10))
126 +
127 + self.organize_btn = tk.Button(
128 + button_frame,
129 + text="🚀 Организирай Desktop",
130 + font=("Segoe UI", 11, "bold"),
131 + bg="#107C10",
132 + fg="white",
133 + padx=20,
134 + pady=10,
135 + cursor="hand2",
136 + command=self.start_organization
137 + )
138 + self.organize_btn.pack(side="left")
139 +
140 + # Лог рамка
141 + log_frame = tk.LabelFrame(
142 + main_frame,
143 + text="📋 Дневник на действията",
144 + font=("Segoe UI", 11, "bold"),
145 + padx=10,
146 + pady=10
147 + )
148 + log_frame.pack(fill="both", expand=True)
149 +
150 + self.log_text = scrolledtext.ScrolledText(
151 + log_frame,
152 + font=("Consolas", 9),
153 + wrap=tk.WORD,
154 + height=15,
155 + state="disabled"
156 + )
157 + self.log_text.pack(fill="both", expand=True)
158 +
159 + # Progress bar
160 + self.progress = ttk.Progressbar(
161 + main_frame,
162 + mode="indeterminate"
163 + )
164 + self.progress.pack(fill="x", pady=(10, 0))
165 +
166 + def log(self, message):
167 + self.log_text.config(state="normal")
168 + timestamp = datetime.now().strftime("%H:%M:%S")
169 + self.log_text.insert(tk.END, f"[{timestamp}] {message}\n")
170 + self.log_text.see(tk.END)
171 + self.log_text.config(state="disabled")
172 + self.root.update()
173 +
174 + def get_category(self, file_path):
175 + ext = file_path.suffix.lower()
176 + for category, extensions in self.categories.items():
177 + if ext in extensions:
178 + return category
179 + return "Други"
180 +
181 + def should_ignore(self, item_path):
182 + # Игнорира системни файлове
183 + if item_path.name in self.system_items:
184 + return True
185 + # Игнорира скрити файлове
186 + if item_path.name.startswith('.'):
187 + return True
188 + return False
189 +
190 + def analyze_desktop(self):
191 + items_to_move = {}
192 + items_to_keep = []
193 +
194 + for item in self.desktop_path.iterdir():
195 + if self.should_ignore(item):
196 + continue
197 +
198 + # Запазва пряки пътища
199 + if self.keep_shortcuts.get() and item.suffix.lower() == ".lnk":
200 + items_to_keep.append(item.name)
201 + continue
202 +
203 + # Запазва папки
204 + if item.is_dir():
205 + if self.keep_folders.get():
206 + items_to_keep.append(item.name)
207 + continue
208 + else:
209 + # Папките ще бъдат преместени в главната папка
210 + if "Папки" not in items_to_move:
211 + items_to_move["Папки"] = []
212 + items_to_move["Папки"].append(item)
213 + continue
214 +
215 + # Категоризира файлове
216 + if item.is_file():
217 + category = self.get_category(item)
218 + if category not in items_to_move:
219 + items_to_move[category] = []
220 + items_to_move[category].append(item)
221 +
222 + return items_to_move, items_to_keep
223 +
224 + def preview_organization(self):
225 + self.log("🔍 Анализиране на Desktop...")
226 + items_to_move, items_to_keep = self.analyze_desktop()
227 +
228 + self.log("\n✅ Файлове/папки, които ще ОСТАНАТ на Desktop:")
229 + if items_to_keep:
230 + for item in items_to_keep:
231 + self.log(f" • {item}")
232 + else:
233 + self.log(" (няма)")
234 +
235 + self.log("\n📦 Файлове, които ще бъдат ОРГАНИЗИРАНИ:")
236 + total_files = 0
237 + for category, files in items_to_move.items():
238 + if files:
239 + self.log(f" 📁 {category}: {len(files)} файла")
240 + total_files += len(files)
241 +
242 + self.log(f"\n📊 Общо файлове за организиране: {total_files}")
243 + self.log("=" * 60)
244 +
245 + def organize_desktop(self):
246 + try:
247 + self.log("🚀 Започване на организация...")
248 + items_to_move, items_to_keep = self.analyze_desktop()
249 +
250 + if not items_to_move:
251 + self.log("✓ Desktop-ът вече е организиран!")
252 + messagebox.showinfo("Готово", "Няма файлове за организиране!")
253 + return
254 +
255 + # Създаване на главна папка
256 + main_folder = self.desktop_path / self.main_folder_name.get()
257 + main_folder.mkdir(exist_ok=True)
258 + self.log(f"✓ Създадена главна папка: {main_folder.name}")
259 +
260 + # Преместване на файлове по категории
261 + moved_count = 0
262 + for category, files in items_to_move.items():
263 + if not files:
264 + continue
265 +
266 + category_folder = main_folder / category
267 + category_folder.mkdir(exist_ok=True)
268 + self.log(f"\n📁 Обработка на категория: {category}")
269 +
270 + for file_path in files:
271 + try:
272 + dest = category_folder / file_path.name
273 +
274 + # Ако файлът съществува, добави номер
275 + if dest.exists():
276 + base = dest.stem
277 + ext = dest.suffix
278 + counter = 1
279 + while dest.exists():
280 + dest = category_folder / f"{base}_{counter}{ext}"
281 + counter += 1
282 +
283 + shutil.move(str(file_path), str(dest))
284 + self.log(f" ✓ Преместен: {file_path.name}")
285 + moved_count += 1
286 + except Exception as e:
287 + self.log(f" ✗ Грешка при преместване на {file_path.name}: {str(e)}")
288 +
289 + self.log(f"\n🎉 Организацията завърши успешно!")
290 + self.log(f"📊 Преместени файлове: {moved_count}")
291 + self.log(f"✓ Запазени на Desktop: {len(items_to_keep)} елемента")
292 +
293 + messagebox.showinfo(
294 + "Успех!",
295 + f"Desktop-ът е организиран успешно!\n\n"
296 + f"Преместени: {moved_count} файла\n"
297 + f"Запазени: {len(items_to_keep)} елемента"
298 + )
299 +
300 + except Exception as e:
301 + self.log(f"❌ ГРЕШКА: {str(e)}")
302 + messagebox.showerror("Грешка", f"Възникна грешка:\n{str(e)}")
303 + finally:
304 + self.progress.stop()
305 + self.organize_btn.config(state="normal")
306 + self.preview_btn.config(state="normal")
307 +
308 + def start_organization(self):
309 + result = messagebox.askyesno(
310 + "Потвърждение",
311 + "Сигурни ли сте, че искате да организирате Desktop-а?\n\n"
312 + "Препоръчваме първо да използвате 'Преглед'."
313 + )
314 +
315 + if result:
316 + self.organize_btn.config(state="disabled")
317 + self.preview_btn.config(state="disabled")
318 + self.progress.start()
319 + self.log_text.config(state="normal")
320 + self.log_text.delete(1.0, tk.END)
321 + self.log_text.config(state="disabled")
322 +
323 + # Стартиране в отделна нишка
324 + thread = threading.Thread(target=self.organize_desktop)
325 + thread.daemon = True
326 + thread.start()
327 +
328 + if __name__ == "__main__":
329 + root = tk.Tk()
330 + app = DesktopOrganizerGUI(root)
331 + root.mainloop()
Daha yeni Daha eski