Paste: asda

Author: asda
Mode: factor
Date: Mon, 16 Mar 2026 05:33:05
Plain Text |
import os
import random
from tkinter import *
from tkinter.messagebox import *
from PIL import Image, ImageTk
from db import Database

database = Database()


class PuzzleCaptcha:
    def __init__(self, parent, user_data, on_success):
        self.top = Toplevel(parent)
        self.top.title("Каптча")
        self.top.geometry("350x450")
        self.top.grab_set()
        self.top.resizable(False, False)

        self.user_data = user_data
        self.on_success = on_success

        self.correct_order = [1, 2, 3, 4]
        self.current_order = [1, 2, 3, 4]
        random.shuffle(self.current_order)

        self.images = {}
        self.selected_index = None
        Label(self.top, text="Соберите пазл").pack(pady=5)
        Label(self.top, text="Кликните на две картинки,\nчтобы поменять их местами.").pack(pady=5)

        self.frame_grid = Frame(self.top)
        self.frame_grid.pack(pady=5)

        if self.load_images():
            self.draw_grid()

        Button(self.top, text="Подтвердить", width=20, command=self.check_result).pack(pady=15)

    def load_images(self):
        try:
            for i in range(1, 5):
                path = os.path.join("img", f"{i}.png")
                img = Image.open(path).resize((120, 120))
                self.images[i] = ImageTk.PhotoImage(img)
            return True
        except Exception as e:
            showerror("Ошибка", f"Не найдены картинки в папке img!\n{e}")
            self.top.destroy()
            return False

    def draw_grid(self):
        for widget in self.frame_grid.winfo_children():
            widget.destroy()

        for index, img_id in enumerate(self.current_order):
            color = "gray" if index == self.selected_index else "white"
            relief = "sunken" if index == self.selected_index else "raised"

            btn = Button(self.frame_grid, image=self.images[img_id],
                         bg=color, relief=relief, bd=3,
                         command=lambda idx=index: self.on_click(idx))

            btn.grid(row=index // 2, column=index % 2, padx=2, pady=2)

    def on_click(self, index):
        if self.selected_index is None:
            self.selected_index = index
        else:
            if self.selected_index == index:
                self.selected_index = None
            else:
                i1, i2 = self.selected_index, index
                self.current_order[i1], self.current_order[i2] = self.current_order[i2], self.current_order[i1]
                self.selected_index = None

        self.draw_grid()
    def check_result(self):
        if self.current_order == self.correct_order:
            self.top.destroy()
            self.on_success()
        else:
            showerror("Ошибка", "Картинка собрана неверно.")


def open_admin_panel():
    adm = Toplevel(root)
    adm.title("Админ-панель")
    adm.geometry("500x450")

    Label(adm, text="Пользователи:").pack()
    text_area = Text(adm, height=12, width=60)
    text_area.pack(pady=5)

    def refresh():
        text_area.delete(1.0, END)
        for u in database.get_all_users():
            text_area.insert(END, f"ID:{u[0]} | Log:{u[1]} | Role:{u[2]} | Ban:{u[3]} | Tries:{u[4]}\n")

    refresh()

    f = Frame(adm)
    f.pack(pady=10)

    Label(f, text="ID:").grid(row=0, column=0)
    e_id = Entry(f, width=5);
    e_id.grid(row=0, column=1)

    Label(f, text="Роль:").grid(row=0, column=2)
    e_role = Entry(f, width=8);
    e_role.grid(row=0, column=3)

    Label(f, text="Забанен(0/1):").grid(row=0, column=4)
    e_ban = Entry(f, width=5);
    e_ban.grid(row=0, column=5)

    def save():
        try:
            uid, urole, uban = e_id.get(), e_role.get(), e_ban.get()
            if uban is None:
                uban = 0

            if uid:
                database.update_user_admin(uid, urole, uban)
                if uban == '0': database.set_tries(uid, 0)
                showinfo("OK", "Обновлено")
                refresh()
        except:
            showerror("Err", "Ошибка ввода")

    Button(adm, text="Сохранить", command=save).pack()


def finalize_login(user, pwd_input):
    uid, ulogin, urole, uban, upass = user[0], user[1], user[2], user[3], user[4]
    utries = user[5] if len(user) > 5 else 0

    if pwd_input == upass:
        database.set_tries(uid, 0)
        if urole == "admin":
            open_admin_panel()
        else:
            showinfo("Успех", f"Добро пожаловать, {ulogin}!")
    else:
        new_tries = utries + 1
        database.set_tries(uid, new_tries)
        if new_tries >= 3:
            database.set_banned(uid, 1)
            showerror("Блок", "3 ошибки. Аккаунт заблокирован.")
        else:
            showerror("Ошибка", f"Неверный пароль ({new_tries}/3)")


def try_login():
    login = e_login.get().strip()
    password = e_pass.get().strip()

    if not login or not password:
        return showwarning("!", "Заполните поля")

    user = database.get_user_by_login(login)
    if not user:
        return showerror("!", "Пользователь не найден")

    if user[3] == 1:
        return showerror("!", "Вы забанены")

    PuzzleCaptcha(root, user, lambda: finalize_login(user, password))


root = Tk()
root.title("Вход")
root.geometry("300x200")

Label(root, text="Логин:").pack(pady=(20, 0))
e_login = Entry(root);
e_login.pack()

Label(root, text="Пароль:").pack()
e_pass = Entry(root, show="*");
e_pass.pack()

Button(root, text="Войти", command=try_login, width=10).pack(pady=20)

root.mainloop()

New Annotation

Summary:
Author:
Mode:
Body: