/
LifeG
/
Cleaner
Обзор
Документация
Войти
/
LifeG
/
Cleaner
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
1
CI/CD
Аналитика
Безопасность
master
Cleaner.py
374 строки
17 KB
LifeG
create: Cleaner.py
22 май 2026, 01:05
Верифицирован
22 май 2026, 01:05
88fd76c
Код
Авторство
О чём код?
import os import shutil from datetime import datetime, timedelta import ctypes import ctypes.wintypes import tkinter as tk from tkinter import ttk, messagebox def get_desktop_path(): """Умный поиск рабочего стола""" try: CSIDL_DESKTOP = 0x0000 buf = ctypes.create_unicode_buffer(260) ctypes.windll.shell32.SHGetFolderPathW(None, CSIDL_DESKTOP, None, 0, buf) return buf.value except: return os.path.join(os.path.expanduser("~"), "Desktop") DESKTOP = get_desktop_path() class CleanerApp: def __init__(self, root): self.root = root self.root.title("Cleaner - Очиститель рабочего стола") self.root.geometry("900x700") self.root.resizable(True, True) # Переменные self.hours_var = tk.StringVar(value="2") self.all_files = [] self.recent_files = [] self.current_files = [] self.selected_files = set() self.file_paths = {} # Создаём интерфейс self.setup_ui() def setup_ui(self): """Создаёт все элементы интерфейса""" # Верхняя панель с информацией info_frame = ttk.LabelFrame(self.root, text="[i] Информация", padding=10) info_frame.pack(fill="x", padx=10, pady=5) ttk.Label(info_frame, text=f"[Folder] Рабочий стол: {DESKTOP}").pack(anchor="w") # Панель управления control_frame = ttk.LabelFrame(self.root, text="[>] Управление", padding=10) control_frame.pack(fill="x", padx=10, pady=5) # Часы hours_frame = ttk.Frame(control_frame) hours_frame.pack(fill="x", pady=5) ttk.Label(hours_frame, text="[Time] Количество часов:").pack(side="left", padx=5) hours_entry = ttk.Entry(hours_frame, textvariable=self.hours_var, width=10) hours_entry.pack(side="left", padx=5) ttk.Label(hours_frame, text="(пример: 2, 1.5, 0.5)").pack(side="left", padx=5) # Кнопки buttons_frame = ttk.Frame(control_frame) buttons_frame.pack(fill="x", pady=10) btn1 = ttk.Button(buttons_frame, text="[1] Показать ВСЕ файлы", command=self.show_all_files) btn1.pack(side="left", padx=5) btn2 = ttk.Button(buttons_frame, text="[2] Показать недавние файлы", command=self.show_recent_files) btn2.pack(side="left", padx=5) btn3 = ttk.Button(buttons_frame, text="[X] Удалить выбранное", command=self.delete_selected) btn3.pack(side="left", padx=5) btn4 = ttk.Button(buttons_frame, text="[D] Удалить всё недавнее", command=self.delete_all_recent) btn4.pack(side="left", padx=5) btn5 = ttk.Button(buttons_frame, text="[-] Снять выделение", command=self.clear_selection) btn5.pack(side="left", padx=5) btn6 = ttk.Button(buttons_frame, text="[R] Обновить", command=self.refresh) btn6.pack(side="left", padx=5) # Область для списка файлов list_frame = ttk.LabelFrame(self.root, text="[List] Список файлов (кликните по [ ] чтобы выбрать)", padding=10) list_frame.pack(fill="both", expand=True, padx=10, pady=5) # Создаём Treeview (таблицу) columns = ("Выбрать", "Тип", "Имя", "Размер", "Дата создания") self.tree = ttk.Treeview(list_frame, columns=columns, show="headings", height=15) # Настраиваем колонки self.tree.heading("Выбрать", text="[X]") self.tree.heading("Тип", text="Тип") self.tree.heading("Имя", text="Имя файла/папки") self.tree.heading("Размер", text="Размер") self.tree.heading("Дата создания", text="Дата создания") self.tree.column("Выбрать", width=60, anchor="center") self.tree.column("Тип", width=80, anchor="center") self.tree.column("Имя", width=400) self.tree.column("Размер", width=100, anchor="center") self.tree.column("Дата создания", width=150, anchor="center") # Добавляем скролл scrollbar_y = ttk.Scrollbar(list_frame, orient="vertical", command=self.tree.yview) scrollbar_x = ttk.Scrollbar(list_frame, orient="horizontal", command=self.tree.xview) self.tree.configure(yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set) self.tree.pack(side="left", fill="both", expand=True) scrollbar_y.pack(side="right", fill="y") scrollbar_x.pack(side="bottom", fill="x") # Привязываем клик для выбора self.tree.bind("<ButtonRelease-1>", self.on_click) # Панель статуса self.status_frame = ttk.LabelFrame(self.root, text="[i] Статус", padding=10) self.status_frame.pack(fill="x", padx=10, pady=5) self.status_label = ttk.Label(self.status_frame, text="[OK] Готов к работе", foreground="green") self.status_label.pack(side="left") self.selected_count_label = ttk.Label(self.status_frame, text="[#] Выбрано: 0", foreground="blue") self.selected_count_label.pack(side="right") def get_file_info(self, path): """Получает информацию о файле""" try: creation_time = os.path.getctime(path) creation_date = datetime.fromtimestamp(creation_time) size = os.path.getsize(path) if size < 1024: size_str = f"{size} байт" elif size < 1024 * 1024: size_str = f"{size // 1024} КБ" else: size_str = f"{size // (1024 * 1024)} МБ" return { 'name': os.path.basename(path), 'date': creation_date, 'date_str': creation_date.strftime('%d.%m.%Y %H:%M:%S'), 'size': size_str, 'path': path, 'is_folder': os.path.isdir(path) } except: return None def update_file_list(self, files): """Обновляет список файлов в таблице""" # Очищаем таблицу for item in self.tree.get_children(): self.tree.delete(item) self.current_files = files self.file_paths = {} self.selected_files = set() # Добавляем файлы в таблицу for f in files: typ = "[DIR]" if f['is_folder'] else "[FILE]" # Добавляем строку с чекбоксом item_id = self.tree.insert("", "end", values=("[ ]", typ, f['name'], f['size'], f['date_str'])) # Сохраняем путь в словаре self.file_paths[item_id] = f self.selected_count_label.config(text=f"[#] Выбрано: 0") def on_click(self, event): """Обработка клика для выбора файла""" region = self.tree.identify_region(event.x, event.y) if region == "cell": column = self.tree.identify_column(event.x) if column == "#1": # Колонка с чекбоксом item = self.tree.identify_row(event.y) if item and item in self.file_paths: current = self.tree.item(item, "values")[0] new_value = "[X]" if current == "[ ]" else "[ ]" values = list(self.tree.item(item, "values")) values[0] = new_value self.tree.item(item, values=values) if new_value == "[X]": self.selected_files.add(item) else: self.selected_files.discard(item) self.selected_count_label.config(text=f"[#] Выбрано: {len(self.selected_files)}") def clear_selection(self): """Снимает все выделения""" for item in self.selected_files.copy(): if item in self.file_paths: values = list(self.tree.item(item, "values")) values[0] = "[ ]" self.tree.item(item, values=values) self.selected_files.clear() self.selected_count_label.config(text="[#] Выбрано: 0") self.status_label.config(text="[OK] Выделение снято", foreground="green") def refresh(self): """Обновляет текущий список""" if hasattr(self, 'current_files') and self.current_files: self.update_file_list(self.current_files) self.status_label.config(text="[OK] Список обновлен", foreground="green") else: self.show_all_files() def get_selected_files_info(self): """Возвращает список выбранных файлов с их информацией""" selected = [] for item in self.selected_files: if item in self.file_paths: selected.append(self.file_paths[item]) return selected def show_all_files(self): """Показывает все файлы на рабочем столе""" self.status_label.config(text="[WAIT] Сбор информации...", foreground="orange") self.root.update() files = [] try: for item in os.listdir(DESKTOP): path = os.path.join(DESKTOP, item) info = self.get_file_info(path) if info: files.append(info) files.sort(key=lambda x: x['name']) self.update_file_list(files) self.status_label.config(text=f"[OK] Загружено {len(files)} файлов/папок", foreground="green") messagebox.showinfo("Готово", f"Найдено {len(files)} элементов на рабочем столе") except Exception as e: self.status_label.config(text=f"[ERR] Ошибка: {e}", foreground="red") messagebox.showerror("Ошибка", str(e)) def show_recent_files(self): """Показывает недавние файлы""" try: hours = float(self.hours_var.get().replace(',', '.')) except: messagebox.showerror("Ошибка", "Введите корректное число часов") return self.status_label.config(text=f"[WAIT] Поиск файлов за последние {hours} часов...", foreground="orange") self.root.update() all_files = [] try: for item in os.listdir(DESKTOP): path = os.path.join(DESKTOP, item) info = self.get_file_info(path) if info: all_files.append(info) now = datetime.now() recent = [] for f in all_files: if now - f['date'] <= timedelta(hours=hours): recent.append(f) recent.sort(key=lambda x: x['date'], reverse=True) self.update_file_list(recent) self.status_label.config(text=f"[OK] Найдено {len(recent)} файлов за последние {hours} часов", foreground="green") messagebox.showinfo("Готово", f"Найдено {len(recent)} файлов, созданных за последние {hours} часов") except Exception as e: self.status_label.config(text=f"[ERR] Ошибка: {e}", foreground="red") messagebox.showerror("Ошибка", str(e)) def delete_selected(self): """Удаляет выбранные файлы""" selected = self.get_selected_files_info() if not selected: messagebox.showwarning("Нет выбора", "Вы не выбрали ни одного файла для удаления") return # Подготовка сообщения file_list = "\n".join([f"{'[DIR]' if f['is_folder'] else '[FILE]'} {f['name']}" for f in selected[:20]]) if len(selected) > 20: file_list += f"\n... и ещё {len(selected) - 20} файлов" result = messagebox.askyesno( "ВНИМАНИЕ! Подтверждение удаления", f"Вы действительно хотите удалить следующие файлы?\n\n{file_list}\n\nВНИМАНИЕ: Эти файлы будут удалены БЕЗВОЗВРАТНО (мимо Корзины)!", icon='warning' ) if result: deleted = 0 errors = 0 for f in selected: try: if f['is_folder']: shutil.rmtree(f['path']) else: os.remove(f['path']) deleted += 1 except Exception as e: errors += 1 messagebox.showinfo("Результат", f"Удалено: {deleted}\nОшибок: {errors}") self.status_label.config(text=f"[OK] Удалено {deleted} файлов", foreground="green") # Обновляем список self.show_all_files() def delete_all_recent(self): """Удаляет все недавние файлы""" try: hours = float(self.hours_var.get().replace(',', '.')) except: messagebox.showerror("Ошибка", "Введите корректное число часов") return self.status_label.config(text=f"[WAIT] Поиск файлов за последние {hours} часов...", foreground="orange") self.root.update() all_files = [] try: for item in os.listdir(DESKTOP): path = os.path.join(DESKTOP, item) info = self.get_file_info(path) if info: all_files.append(info) now = datetime.now() recent = [] for f in all_files: if now - f['date'] <= timedelta(hours=hours): recent.append(f) if not recent: messagebox.showinfo("Нет файлов", f"Нет файлов, созданных за последние {hours} часов") return file_list = "\n".join([f"{'[DIR]' if f['is_folder'] else '[FILE]'} {f['name']}" for f in recent[:20]]) if len(recent) > 20: file_list += f"\n... и ещё {len(recent) - 20} файлов" result = messagebox.askyesno( "ВНИМАНИЕ! ПОДТВЕРЖДЕНИЕ УДАЛЕНИЯ", f"Будет удалено {len(recent)} файлов/папок, созданных за последние {hours} часов:\n\n{file_list}\n\nВЫ УВЕРЕНЫ?", icon='warning' ) if result: deleted = 0 errors = 0 for f in recent: try: if f['is_folder']: shutil.rmtree(f['path']) else: os.remove(f['path']) deleted += 1 except Exception as e: errors += 1 messagebox.showinfo("Результат", f"Удалено: {deleted}\nОшибок: {errors}") self.status_label.config(text=f"[OK] Удалено {deleted} файлов", foreground="green") self.show_all_files() except Exception as e: self.status_label.config(text=f"[ERR] Ошибка: {e}", foreground="red") messagebox.showerror("Ошибка", str(e)) if __name__ == "__main__": root = tk.Tk() app = CleanerApp(root) root.mainloop()