Termuxの残骸やキャッシュを削除するツール

import os
import shutil
import tkinter as tk
from tkinter import messagebox

class TermuxAdvancedCleaner:
    def __init__(self, root):
        self.root = root
        self.root.title("Termux Selective Cleaner")
        self.root.geometry("600x700")

        # 掃除の対象にする親ディレクトリ
        self.base_paths = [
            "/data/data/com.termux/files/home/.cache",
            "/data/data/com.termux/files/usr/tmp",
            "/data/data/com.termux/files/home/.pip/cache",
            "/data/data/com.termux/files/home/.npm/_cacache"
        ]
        
        self.items_to_clean = [] # (チェック状態, パス) のリスト
        self.create_widgets()
        self.scan_files()

    def create_widgets(self):
        tk.Label(self.root, text="削除する項目を選択してください", font=("Arial", 14, "bold")).pack(pady=10)

        # スクロール可能なリストエリア
        self.list_frame = tk.Frame(self.root)
        self.list_frame.pack(fill=tk.BOTH, expand=True, padx=10)

        self.canvas = tk.Canvas(self.list_frame)
        self.scrollbar = tk.Scrollbar(self.list_frame, orient="vertical", command=self.canvas.yview)
        self.scrollable_frame = tk.Frame(self.canvas)

        self.scrollable_frame.bind(
            "",
            lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all"))
        )

        self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
        self.canvas.configure(yscrollcommand=self.scrollbar.set)

        self.canvas.pack(side="left", fill="both", expand=True)
        self.scrollbar.pack(side="right", fill="y")

        # ボタンエリア
        btn_frame = tk.Frame(self.root)
        btn_frame.pack(pady=20)

        tk.Button(btn_frame, text="再スキャン", command=self.scan_files, bg="#3498db", fg="white").pack(side=tk.LEFT, padx=5)
        tk.Button(btn_frame, text="選択した項目を削除", command=self.delete_selected, bg="#e74c3c", fg="white", font=("Arial", 12, "bold")).pack(side=tk.LEFT, padx=5)

    def scan_files(self):
        # リストをクリア
        for widget in self.scrollable_frame.winfo_children():
            widget.destroy()
        self.items_to_clean = []

        found_any = False
        for base in self.base_paths:
            if os.path.exists(base):
                try:
                    for item in os.listdir(base):
                        full_path = os.path.join(base, item)
                        var = tk.BooleanVar(value=True) # デフォルトでチェックあり
                        cb = tk.Checkbutton(self.scrollable_frame, text=f"[{os.path.basename(base)}] {item}", variable=var, anchor="w")
                        cb.pack(fill=tk.X, padx=5)
                        self.items_to_clean.append((var, full_path))
                        found_any = True
                except Exception as e:
                    tk.Label(self.scrollable_frame, text=f"Error reading {base}", fg="red").pack()

        if not found_any:
            tk.Label(self.scrollable_frame, text="ゴミは見つかりませんでした。").pack(pady=20)

    def delete_selected(self):
        targets = [path for var, path in self.items_to_clean if var.get()]
        
        if not targets:
            messagebox.showwarning("警告", "削除する項目が選択されていません。")
            return

        if messagebox.askyesno("最終確認", f"選択された {len(targets)} 個の項目を完全に削除しますか?"):
            deleted_count = 0
            for path in targets:
                try:
                    if os.path.isfile(path) or os.path.islink(path):
                        os.unlink(path)
                    elif os.path.isdir(path):
                        shutil.rmtree(path)
                    deleted_count += 1
                except Exception as e:
                    print(f"Failed to delete {path}: {e}")

            messagebox.showinfo("完了", f"{deleted_count} 個の項目を削除しました。")
            self.scan_files() # リストを更新

if __name__ == "__main__":
    root = tk.Tk()
    app = TermuxAdvancedCleaner(root)
    root.mainloop()

コメント

このブログの人気の投稿

ミライアイ内服薬は薬事法違反で、ほとんど効果がない詐欺ですか?

最高裁での上告理由書受理・却下の判断基準について

裁判官の忌避申立書の作成例