Facebook
From 1, 1 Month ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 126
  1. import tkinter as tk
  2. from tkinter import messagebox, filedialog, Menu, Scrollbar, Frame, Canvas
  3. import sqlite3
  4. import hashlib
  5. import datetime
  6.  
  7. class DatabaseManager:
  8.     def __init__(self, db_path):
  9.         self.db_path = db_path
  10.         self.create_tables()
  11.         self.alter_table()
  12.  
  13.     def create_tables(self):
  14.         with sqlite3.connect(self.db_path) as conn:
  15.             c = conn.cursor()
  16.             c.execute('''
  17.                 CREATE TABLE IF NOT EXISTS users (
  18.                     id INTEGER PRIMARY KEY AUTOINCREMENT,
  19.                     username TEXT UNIQUE,
  20.                     password TEXT
  21.                 )''')
  22.             c.execute('''
  23.                 CREATE TABLE IF NOT EXISTS projects (
  24.                     id INTEGER PRIMARY KEY AUTOINCREMENT,
  25.                     name TEXT,
  26.                     type TEXT,
  27.                     start_date TEXT,
  28.                     end_date TEXT,
  29.                     completed INTEGER DEFAULT 0,
  30.                     user_id INTEGER,
  31.                     file_path TEXT,
  32.                     FOREIGN KEY (user_id) REFERENCES users (id)
  33.                 )''')
  34.             conn.commit()
  35.  
  36.     def alter_table(self):
  37.         with sqlite3.connect(self.db_path) as conn:
  38.             c = conn.cursor()
  39.             try:
  40.                 c.execute("ALTER TABLE projects ADD COLUMN file_path TEXT")
  41.                 conn.commit()
  42.             except sqlite3.OperationalError:
  43.                 pass
  44.  
  45.     def execute_query(self, query, params=(), fetch=False):
  46.         with sqlite3.connect(self.db_path) as conn:
  47.             c = conn.cursor()
  48.             c.execute(query, params)
  49.             if fetch:
  50.                 return c.fetchall()
  51.             conn.commit()
  52.  
  53. class AuthenticationManager(DatabaseManager):
  54.     def hash_password(self, password):
  55.         return hashlib.sha256(password.encode()).hexdigest()
  56.  
  57.     def register_user(self, username, password):
  58.         hashed_password = self.hash_password(password)
  59.         try:
  60.             self.execute_query("INSERT INTO users (username, password) VALUES (?, ?)", (username, hashed_password))
  61.             messagebox.showinfo("Успех", "Пользователь успешно зарегистрирован.")
  62.         except sqlite3.IntegrityError:
  63.             messagebox.showerror("Ошибка", "Пользователь с таким именем уже существует.")
  64.  
  65.     def authenticate(self, username, password):
  66.         hashed_password = self.hash_password(password)
  67.         user = self.execute_query("SELECT * FROM users WHERE username=? AND password=?", (username, hashed_password), fetch=True)
  68.         if user:
  69.             return user[0][0]
  70.         messagebox.showerror("Ошибка", "Неправильный логин или пароль")
  71.         return None
  72.  
  73.     def delete_user(self, user_id):
  74.         self.execute_query("DELETE FROM users WHERE id=?", (user_id,))
  75.         self.execute_query("DELETE FROM projects WHERE user_id=?", (user_id,))
  76.  
  77. class Application(tk.Tk):
  78.     def __init__(self, db_manager):
  79.         super().__init__()
  80.         self.db_manager = db_manager
  81.         self.title("TaskBoard - Вход и регистрация")
  82.         self.geometry("600x400")
  83.         self.center_window(600, 400)
  84.         self.create_widgets()
  85.  
  86.     def center_window(self, width, height):
  87.         screen_width = self.winfo_screenwidth()
  88.         screen_height = self.winfo_screenheight()
  89.         x = (screen_width - width) // 2
  90.         y = (screen_height - height) // 2
  91.         self.geometry(f"{width}x{height}+{x}+{y}")
  92.  
  93.     def create_widgets(self):
  94.         tk.Label(self, text="Логин:", font=("Helvetica", 14)).grid(row=0, column=0, sticky=tk.W, padx=10, pady=10)
  95.         self.entry_username = tk.Entry(self, font=("Helvetica", 14))
  96.         self.entry_username.grid(row=0, column=1, sticky=(tk.W, tk.E), padx=10, pady=10)
  97.  
  98.         tk.Label(self, text="Пароль:", font=("Helvetica", 14)).grid(row=1, column=0, sticky=tk.W, padx=10, pady=10)
  99.         self.entry_password = tk.Entry(self, show="*", font=("Helvetica", 14))
  100.         self.entry_password.grid(row=1, column=1, sticky=(tk.W, tk.E), padx=10, pady=10)
  101.  
  102.         tk.Button(self, text="Вход", command=self.login, font=("Helvetica", 14)).grid(row=2, column=0, columnspan=2, pady=10)
  103.         tk.Button(self, text="Регистрация", command=self.register, font=("Helvetica", 14)).grid(row=3, column=0, columnspan=2, pady=10)
  104.         tk.Button(self, text="Список пользователей", command=self.show_users, font=("Helvetica", 14)).grid(row=4, column=0, columnspan=2, pady=10)
  105.  
  106.         self.grid_columnconfigure(0, weight=1)
  107.         self.grid_columnconfigure(1, weight=1)
  108.  
  109.     def login(self):
  110.         username = self.entry_username.get()
  111.         password = self.entry_password.get()
  112.         user_id = self.db_manager.authenticate(username, password)
  113.         if user_id:
  114.             self.destroy()
  115.             MainWindow(self.db_manager, user_id)
  116.  
  117.     def register(self):
  118.         username = self.entry_username.get()
  119.         password = self.entry_password.get()
  120.         self.db_manager.register_user(username, password)
  121.  
  122.     def show_users(self):
  123.         users = self.db_manager.execute_query("SELECT username FROM users", fetch=True)
  124.         users_window = tk.Toplevel(self)
  125.         users_window.title("Список пользователей")
  126.         users_window.geometry("300x200")
  127.         self.center_window_in_window(users_window, 300, 200)
  128.         for user in users:
  129.             user_label = tk.Label(users_window, text=f"Пользователь: {user[0]}", font=("Helvetica", 12))
  130.             user_label.pack(anchor='w', padx=10, pady=5)
  131.  
  132.     def center_window_in_window(self, window, width, height):
  133.         screen_width = window.winfo_screenwidth()
  134.         screen_height = window.winfo_screenheight()
  135.         x = (screen_width - width) // 2
  136.         y = (screen_height - height) // 2
  137.         window.geometry(f"{width}x{height}+{x}+{y}")
  138.  
  139. class MainWindow(tk.Tk):
  140.     def __init__(self, db_manager, user_id):
  141.         super().__init__()
  142.         self.db_manager = db_manager
  143.         self.user_id = user_id
  144.         self.title("TaskBoard - Личный кабинет")
  145.         self.geometry("800x600")
  146.         self.center_window(800, 600)
  147.         self.create_widgets()
  148.         self.update_time()
  149.  
  150.     def center_window(self, width, height):
  151.         screen_width = self.winfo_screenwidth()
  152.         screen_height = self.winfo_screenheight()
  153.         x = (screen_width - width) // 2
  154.         y = (screen_height - height) // 2
  155.         self.geometry(f"{width}x{height}+{x}+{y}")
  156.  
  157.     def create_widgets(self):
  158.         self.current_time_label = tk.Label(self, text="", font=("Helvetica", 14))
  159.         self.current_time_label.grid(row=0, column=0, columnspan=3, pady=10)
  160.  
  161.         tk.Button(self, text="Проекты", command=self.open_projects_window, font=("Helvetica", 14)).grid(row=1, column=0, columnspan=3, pady=10)
  162.         tk.Button(self, text="Удалить свой аккаунт", command=self.delete_own_account, font=("Helvetica", 14)).grid(row=2, column=0, columnspan=3, pady=10)
  163.         tk.Button(self, text="Выход", command=self.logout, font=("Helvetica", 14)).grid(row=3, column=0, columnspan=3, pady=10)
  164.  
  165.         self.grid_columnconfigure(0, weight=1)
  166.         self.grid_columnconfigure(1, weight=1)
  167.         self.grid_columnconfigure(2, weight=1)
  168.  
  169.     def open_projects_window(self):
  170.         self.withdraw()
  171.         ProjectsWindow(self.db_manager, self.user_id, self)
  172.  
  173.     def update_time(self):
  174.         now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  175.         self.current_time_label.config(text=now)
  176.         self.after(1000, self.update_time)
  177.  
  178.     def show_users(self):
  179.         users = self.db_manager.execute_query("SELECT username FROM users", fetch=True)
  180.         users_window = tk.Toplevel(self)
  181.         users_window.title("Список пользователей")
  182.         users_window.geometry("400x300")
  183.         self.center_window_in_window(users_window, 400, 300)
  184.         for user in users:
  185.             user_label = tk.Label(users_window, text=f"Пользователь: {user[0]}", font=("Helvetica", 12))
  186.             user_label.pack(anchor='w', padx=10, pady=5)
  187.  
  188.     def delete_own_account(self):
  189.         if messagebox.askyesno("Подтверждение", "Вы уверены, что хотите удалить свой аккаунт?"):
  190.             self.db_manager.delete_user(self.user_id)
  191.             messagebox.showinfo("Успех", "Ваш аккаунт успешно удален.")
  192.             self.logout()
  193.  
  194.     def logout(self):
  195.         self.destroy()
  196.         app = Application(self.db_manager)
  197.         app.mainloop()
  198.  
  199. class ProjectsWindow(tk.Toplevel):
  200.     def __init__(self, db_manager, user_id, parent):
  201.         super().__init__()
  202.         self.db_manager = db_manager
  203.         self.user_id = user_id
  204.         self.parent = parent
  205.         self.title("TaskBoard - Проекты")
  206.         self.geometry("800x600")
  207.         self.center_window(800, 600)
  208.         self.create_widgets()
  209.         self.update_time()
  210.  
  211.     def center_window(self, width, height):
  212.         screen_width = self.winfo_screenwidth()
  213.         screen_height = self.winfo_screenheight()
  214.         x = (screen_width - width) // 2
  215.         y = (screen_height - height) // 2
  216.         self.geometry(f"{width}x{height}+{x}+{y}")
  217.  
  218.     def create_widgets(self):
  219.         self.current_time_label = tk.Label(self, text="", font=("Helvetica", 14))
  220.         self.current_time_label.grid(row=0, column=0, columnspan=3, pady=10)
  221.  
  222.         tk.Label(self, text="Название проекта:", font=("Helvetica", 14)).grid(row=1, column=0, sticky=tk.W, padx=10, pady=10)
  223.         self.entry_project_name = tk.Entry(self, font=("Helvetica", 14))
  224.         self.entry_project_name.grid(row=1, column=1, columnspan=2, sticky=(tk.W, tk.E), padx=10, pady=10)
  225.  
  226.         tk.Label(self, text="Тип проекта:", font=("Helvetica", 14)).grid(row=2, column=0, sticky=tk.W, padx=10, pady=10)
  227.         self.entry_project_type = tk.Entry(self, font=("Helvetica", 14))
  228.         self.entry_project_type.grid(row=2, column=1, columnspan=2, sticky=(tk.W, tk.E), padx=10, pady=10)
  229.  
  230.         tk.Label(self, text="Дата начала:", font=("Helvetica", 14)).grid(row=3, column=0, sticky=tk.W, padx=10, pady=10)
  231.         self.entry_start_date = tk.Entry(self, font=("Helvetica", 14))
  232.         self.entry_start_date.grid(row=3, column=1, columnspan=2, sticky=(tk.W, tk.E), padx=10, pady=10)
  233.  
  234.         tk.Label(self, text="Дата окончания:", font=("Helvetica", 14)).grid(row=4, column=0, sticky=tk.W, padx=10, pady=10)
  235.         self.entry_end_date = tk.Entry(self, font=("Helvetica", 14))
  236.         self.entry_end_date.grid(row=4, column=1, columnspan=2, sticky=(tk.W, tk.E), padx=10, pady=10)
  237.  
  238.         tk.Label(self, text="Прикрепленный файл:", font=("Helvetica", 14)).grid(row=5, column=0, sticky=tk.W, padx=10, pady=10)
  239.         self.entry_file_path = tk.Entry(self, font=("Helvetica", 14))
  240.         self.entry_file_path.grid(row=5, column=1, sticky=(tk.W, tk.E), padx=10, pady=10)
  241.         tk.Button(self, text="Выбрать файл", command=self.select_file, font=("Helvetica", 14)).grid(row=5, column=2, sticky=(tk.W, tk.E), padx=10, pady=10)
  242.  
  243.         tk.Button(self, text="Добавить проект", command=self.add_project, font=("Helvetica", 14)).grid(row=6, column=0, columnspan=3, pady=10)
  244.  
  245.         # Создание области прокрутки для списка проектов
  246.         self.canvas = Canvas(self)
  247.         self.canvas.grid(row=7, column=0, columnspan=3, sticky=(tk.W, tk.E, tk.N, tk.S))
  248.         self.scrollbar = Scrollbar(self, orient="vertical", command=self.canvas.yview)
  249.         self.scrollbar.grid(row=7, column=3, sticky=(tk.N, tk.S))
  250.         self.canvas.configure(yscrollcommand=self.scrollbar.set)
  251.  
  252.         self.project_frame = Frame(self.canvas)
  253.         self.canvas.create_window((0, 0), window=self.project_frame, anchor='nw')
  254.  
  255.         self.project_frame.bind("<Configure>", lambda event: self.canvas.configure(scrollregion=self.canvas.bbox("all")))
  256.  
  257.         self.display_projects()
  258.  
  259.         tk.Button(self, text="Выход", command=self.close_window, font=("Helvetica", 14)).grid(row=8, column=0, columnspan=3, pady=10)
  260.  
  261.         self.grid_columnconfigure(0, weight=1)
  262.         self.grid_columnconfigure(1, weight=1)
  263.         self.grid_columnconfigure(2, weight=1)
  264.  
  265.     def update_time(self):
  266.         now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  267.         self.current_time_label.config(text=now)
  268.         self.after(1000, self.update_time)
  269.  
  270.     def select_file(self):
  271.         file_path = filedialog.askopenfilename()
  272.         if file_path:
  273.             self.entry_file_path.delete(0, tk.END)
  274.             self.entry_file_path.insert(0, file_path)
  275.  
  276.     def add_project(self):
  277.         project_name = self.entry_project_name.get()
  278.         project_type = self.entry_project_type.get()
  279.         start_date = self.entry_start_date.get()
  280.         end_date = self.entry_end_date.get()
  281.         file_path = self.entry_file_path.get()
  282.         self.db_manager.execute_query(
  283.             "INSERT INTO projects (name, type, start_date, end_date, file_path, user_id) VALUES (?, ?, ?, ?, ?, ?)",
  284.             (project_name, project_type, start_date, end_date, file_path, self.user_id)
  285.         )
  286.         self.display_projects()
  287.  
  288.     def display_projects(self):
  289.         for widget in self.project_frame.winfo_children():
  290.             widget.destroy()
  291.         projects = self.db_manager.execute_query(
  292.             "SELECT id, name, type, start_date, end_date, completed, file_path FROM projects WHERE user_id=?",
  293.             (self.user_id,), fetch=True)
  294.         for project in projects:
  295.             project_frame = Frame(self.project_frame, padx=10, pady=5, relief=tk.RAISED, bd=2)
  296.             project_frame.pack(fill='x', expand=True, pady=5)
  297.  
  298.             text = f"{project[1]} - {project[2]} - {project[3]} to {project[4]}"
  299.             label = tk.Label(project_frame, text=text,
  300.                              font=("Helvetica", 12, "overstrike" if project[5] else "normal"))
  301.             label.pack(anchor='w')
  302.  
  303.             if project[6]:
  304.                 file_label = tk.Label(project_frame, text=f"Файл: {project[6]}", font=("Helvetica", 12))
  305.                 file_label.pack(anchor='w')
  306.  
  307.             chk_state = tk.BooleanVar(value=project[5])
  308.             chk = tk.Checkbutton(project_frame, variable=chk_state,
  309.                                  command=lambda p=project[0], s=chk_state: self.toggle_project(p, s))
  310.             chk.pack(anchor='w')
  311.  
  312.             btn_delete = tk.Button(project_frame, text="Удалить",
  313.                                    command=lambda p=project[0]: self.delete_project(p), font=("Helvetica", 12))
  314.             btn_delete.pack(anchor='w')
  315.  
  316.             project_name = project[1]
  317.             project_time = project[4].split('.')
  318.             day = int(project_time[0])
  319.             month = int(project_time[1])
  320.             year = int(project_time[2])
  321.             now = datetime.datetime.now()
  322.             DAYS_BEFORE = 2
  323.             if not project[5]:
  324.                 if now.year == year and now.month == month:
  325.                     if now.day > day - DAYS_BEFORE:
  326.                         messagebox.showerror("Важно", "До сдачи проекта " + project_name + " осталось менее " + str(
  327.                             DAYS_BEFORE) + " суток")
  328.                     elif now.day == day:
  329.                         messagebox.showerror("Важно", "Сегодня день сдачи проекта " + project_name)
  330.                     elif now.day > day:
  331.                         messagebox.showerror("Важно", "Проект " + project_name + " просрочен!")
  332.                 elif now.year > year или (now.year == year и теперь.month > month):
  333.                     messagebox.showerror("Важно", "Проект " + project_name + " просрочен!")
  334.  
  335.     def toggle_project(self, project_id, state):
  336.         self.db_manager.execute_query("UPDATE projects SET completed = ? WHERE id = ?", (state.get(), project_id))
  337.         self.display_projects()
  338.  
  339.     def delete_project(self, project_id):
  340.         self.db_manager.execute_query("DELETE FROM projects WHERE id = ?", (project_id,))
  341.         self.display_projects()
  342.  
  343.     def close_window(self):
  344.         self.destroy()
  345.         self.parent.deiconify()
  346.  
  347. if __name__ == "__main__":
  348.     db_path = 'users.db'
  349.     db_manager = AuthenticationManager(db_path)
  350.     app = Application(db_manager)
  351.     app.mainloop()
  352.