Make It Simple – Python Kaynak Kodu


import customtkinter as ctk
from tkinter import messagebox
import os
import sys
import yaml
import hashlib
import logging
import random
import time
import math
import psutil
import subprocess

# Os environment 
APPDATA = os.getenv('APPDATA') or os.path.expanduser("~")
PROGRAM_FOLDER = os.path.join(APPDATA, "Make_It_Simple")
SETTINGS_PATH = os.path.join(PROGRAM_FOLDER, "settings.yml")
SECRETS_PATH = os.path.join(PROGRAM_FOLDER, "secrets.yml")
EXTENTIONS_FOLDER = os.path.join(PROGRAM_FOLDER, "extensions")

os.makedirs(PROGRAM_FOLDER, exist_ok=True)
os.makedirs(EXTENTIONS_FOLDER, exist_ok=True)

# Configure logging
logging.basicConfig(
    filename=f"{APPDATA}/Make_It_Simple/error.log",
    level=logging.ERROR,
    format="%(asctime)s | %(levelname)s | %(message)s"
)

def tum_hatalari_yakala(exc_type, exc_value, exc_traceback):
    logging.critical(
        "YAKALANMAYAN KRİTİK HATA",
        exc_info=(exc_type, exc_value, exc_traceback)
    )

sys.excepthook = tum_hatalari_yakala

# Default settings
default_settings = {
    "theme": "dark",
    "auto_update": True
}

def set_settings_to_default():
    ctk.set_appearance_mode("dark")
    with open(SETTINGS_PATH, 'w') as f:
        yaml.dump(default_settings, f)

def reset_secrets(token: str) -> str:
    """Tokeni SHA256 ile hashler."""
    return hashlib.sha256(str(token).encode()).hexdigest()

FIRST_RUN = False
READABLE_TOKEN = None  # Kullanıcıya gösterilecek ilk token

def load_settings():
    global settings
    if not os.path.exists(SETTINGS_PATH):
        set_settings_to_default()
    try:
        with open(SETTINGS_PATH, "r") as f:
            settings = yaml.safe_load(f) or default_settings
    except Exception:
        logging.exception("settings.yml okunamadı, varsayılan yüklendi")
        settings = default_settings
    ctk.set_appearance_mode(settings.get("theme", "dark"))

def load_secrets():
    global secrets, FIRST_RUN, READABLE_TOKEN
    if not os.path.exists(SECRETS_PATH):
        # İlk kez çalışıyorsa: kullanıcı için rastgele bir token üret
        FIRST_RUN = True
        READABLE_TOKEN = random.randint(100000, 999999)
        token_hash = reset_secrets(READABLE_TOKEN)
        secrets = {"token": token_hash}
        with open(SECRETS_PATH, "w") as f:
            yaml.dump(secrets, f)
    else:
        try:
            with open(SECRETS_PATH, "r") as f:
                secrets = yaml.safe_load(f) or {}
        except Exception:
            logging.exception("secrets.yml okunamadı")
            secrets = {}

# =========================
# Güvenlik: Token doğrulama
# =========================
def check_token(action_text: str) -> bool:
    """
    Her kritik işlemden önce token ister.
    Token doğruysa True, yanlışsa False döner.
    """
    if "token" not in secrets:
        messagebox.showerror("Güvenlik Hatası", "Güvenlik tokeni bulunamadı.")
        return False

    # CustomTkinter Input Dialog
    dialog = ctk.CTkInputDialog(
        text=f"{action_text} için güvenlik tokenini girin:",
        title="Güvenlik Doğrulama"
    )
    entered = dialog.get_input()

    if not entered:
        return False

    if reset_secrets(entered) == secrets.get("token"):
        return True

    messagebox.showerror("Hatalı Token", "Güvenlik tokeni yanlış.")
    return False


# Starting point
load_settings()
load_secrets()

app = ctk.CTk()
app.withdraw()  # Ana pencere sadece yüklenme/splash bittikten sonra açılacak

# İlk çalıştırmada tokeni kullanıcıya göster
if FIRST_RUN and READABLE_TOKEN is not None:
    # Tk arayüzü hazır olsun diye küçük bir gecikme ile gösteriyoruz
    app.after(100, lambda: messagebox.showinfo(
        "Güvenlik Tokeni",
        f"İlk güvenlik tokeniniz:\n\n{READABLE_TOKEN}\n\nBu kodu bir yere not etmeyi unutmayın!"
    ))

# =========================
# CTK ÜST MENÜ (PROGRAM MENÜSÜ)
# =========================
top_menu = ctk.CTkFrame(app, height=50, fg_color="#1f1f1f")
top_menu.pack(fill="x")

menu_title = ctk.CTkLabel(
    top_menu,
    text="Make It Simple",
    font=ctk.CTkFont(size=18, weight="bold")
)
menu_title.pack(side="left", padx=15)

# Menü Fonksiyonları (TOKEN KORUMALI)
def close_ps():
    if not check_token("Bilgisayarı kapatmak"):
        return
    messagebox.showinfo("Kapanış", "Bilgisayar 1 saniye içinde kapanacak.")
    os.system("shutdown /s /t 1")

def restart_ps():
    if not check_token("Bilgisayarı yeniden başlatmak"):
        return
    messagebox.showinfo("Yeniden Başlatma", "Bilgisayar yeniden başlatılacak.")
    os.system("shutdown /r /t 1")

def sleep_ps():
    if not check_token("Bilgisayarı uyku moduna almak"):
        return
    messagebox.showinfo("Uyku Modu", "Bilgisayar uyku moduna geçiyor.")
    os.system("rundll32.exe powrprof.dll,SetSuspendState 0,1,0")

def close_process():
    if not check_token("Programdan çıkmak"):
        return
    app.destroy()

# KAPAT / YENİDEN BAŞLAT / UYKU / ÇIKIŞ BUTONLARI
ctk.CTkButton(top_menu, text="Kapat", command=close_ps, width=90).pack(side="right", padx=5, pady=8)
ctk.CTkButton(top_menu, text="Yeniden Başlat", command=restart_ps, width=130).pack(side="right", padx=5)
ctk.CTkButton(top_menu, text="Uyku", command=sleep_ps, width=90).pack(side="right", padx=5)
ctk.CTkButton(top_menu, text="Çıkış", command=close_process, width=90).pack(side="right", padx=10)


# =========================
# YÜKLENME (SPLASH) EKRANI
# =========================
load_screen = ctk.CTkToplevel(app)
load_screen.geometry("400x200")
load_screen.title("Yükleniyor...")
load_screen.resizable(False, False)

load_frame = ctk.CTkFrame(load_screen)
load_frame.pack(expand=True, fill="both", padx=20, pady=20)

canvas = ctk.CTkCanvas(load_frame, width=200, height=100, bg="#1a1a1a", highlightthickness=0)
canvas.pack(pady=20)

angle = 0
ANIMATION_WAIT_TIME = 3000
start_time = time.time()

def animate_loader():
    global angle, start_time

    if (time.time() - start_time) * 1000 > ANIMATION_WAIT_TIME:
        load_screen.withdraw()     # Splash gizlenir
        app.deiconify()            # Ana pencere açılır
        return

    canvas.delete("all")
    x0, y0 = 100, 50
    r = 25

    for i in range(10):
        rad = math.radians(angle + i * 36)
        x = x0 + r * math.cos(rad)
        y = y0 + r * math.sin(rad)
        canvas.create_oval(x-4, y-4, x+4, y+4, fill="#00aaff", outline="")

    angle = (angle + 8) % 360
    load_screen.after(40, animate_loader)

animate_loader()


# =========================
# ANA PENCERE İÇERİĞİ
# =========================
app.title("Make It Simple")
app.geometry("800x600")

main_frame = ctk.CTkFrame(app)
main_frame.pack(expand=True, fill="both", padx=20, pady=20)

ctk.CTkLabel(
    main_frame,
    text="İşletim Sistemi Kontrol Paneli",
    font=ctk.CTkFont(size=20, weight="bold")
).pack(pady=20)

# Sistem bilgi label'ları
ram_label = ctk.CTkLabel(main_frame, font=ctk.CTkFont(size=16))
cpu_label = ctk.CTkLabel(main_frame, font=ctk.CTkFont(size=16))
disk_label = ctk.CTkLabel(main_frame, font=ctk.CTkFont(size=16))
battery_label = ctk.CTkLabel(main_frame, font=ctk.CTkFont(size=16))

ram_label.pack(pady=5)
cpu_label.pack(pady=5)
disk_label.pack(pady=5)
battery_label.pack(pady=5)

# CANLI SİSTEM GÜNCELLEME
def update_system():
    try:
        ram = psutil.virtual_memory().percent
        cpu = psutil.cpu_percent()
        disk = psutil.disk_usage('C:/').percent
    except Exception as e:
        logging.exception("Sistem bilgisi okunamadı")
        ram = cpu = disk = 0

    ram_label.configure(text=f"RAM Kullanımı: {ram}%")
    cpu_label.configure(text=f"CPU Kullanımı: {cpu}%")
    disk_label.configure(text=f"Disk Kullanımı: {disk}%")

    try:
        battery = psutil.sensors_battery()
        if battery:
            battery_label.configure(
                text=f"Batarya: {battery.percent}% {'(Şarj Oluyor)' if battery.power_plugged else ''}"
            )
        else:
            battery_label.configure(text="Batarya: Yok")
    except Exception:
        battery_label.configure(text="Batarya bilgisi okunamadı")

    app.after(1000, update_system)

update_system()

# ZAMANLI KAPATMA (TOKEN KORUMALI)
shutdown_entry = ctk.CTkEntry(main_frame, placeholder_text="Kapanma süresi (saniye)")
shutdown_entry.pack(pady=10)

def schedule_shutdown():
    if not check_token("Zamanlı kapatma ayarlamak"):
        return
    try:
        sec = int(shutdown_entry.get())
        if sec < 1:
            raise ValueError
        subprocess.run(f"shutdown /s /t {sec}", shell=True)
        messagebox.showinfo("Zamanlı Kapatma", f"Bilgisayar {sec} saniye sonra kapanacak.")
    except Exception:
        messagebox.showwarning("Hata", "Lütfen geçerli bir saniye değeri girin.")

ctk.CTkButton(main_frame, text="Zamanlı Kapat", command=schedule_shutdown).pack(pady=10)

app.mainloop()