Files
Kur3ab/beta2/universal_git_analyzer_gui_final2/main.py

245 lines
9.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import tkinter as tk
from tkinter import messagebox
import threading
from analyzer import analyze_repository
from storage import register_user, check_user, get_repositories, add_repository, delete_repository
class GitAnalyzerApp:
def __init__(self):
self.root = tk.Tk()
self.root.title('Universal Git Analyzer')
self.root.geometry('1200x750')
self.root.minsize(1000, 650)
self.root.resizable(True, True)
self.current_user = None
self.bg = '#eef4ff'
self.panel = '#ffffff'
self.button = '#6aa6ff'
self.root.configure(bg=self.bg)
self.show_splash()
self.root.mainloop()
def clear(self):
for widget in self.root.winfo_children():
widget.destroy()
def make_button(self, parent, text, command, width=24):
return tk.Button(
parent,
text=text,
command=command,
width=width,
bg=self.button,
fg='white',
activebackground='#4d8ee8',
font=('Arial', 12, 'bold'),
relief='flat',
cursor='hand2',
pady=6,
)
def show_splash(self):
self.clear()
frame = tk.Frame(self.root, bg=self.bg)
frame.pack(expand=True)
tk.Label(
frame,
text='Universal Git Analyzer',
font=('Arial', 30, 'bold'),
bg=self.bg,
fg='#1d3557',
).pack(pady=20)
tk.Label(
frame,
text='Анализ Git-репозиториев: GitHub, Gitea, GitLab и другие публичные git-ссылки',
font=('Arial', 14),
bg=self.bg,
fg='#333333',
).pack(pady=10)
tk.Label(frame, text='Загрузка...', font=('Arial', 12), bg=self.bg, fg='#555555').pack(pady=30)
self.root.after(1200, self.show_login)
def show_login(self):
self.clear()
frame = tk.Frame(self.root, bg=self.panel, padx=35, pady=35)
frame.place(relx=0.5, rely=0.5, anchor='center')
tk.Label(frame, text='Вход в аккаунт', font=('Arial', 22, 'bold'), bg=self.panel).pack(pady=10)
tk.Label(frame, text='Логин', bg=self.panel, font=('Arial', 11)).pack(anchor='w')
login_entry = tk.Entry(frame, width=35, font=('Arial', 12))
login_entry.pack(pady=5)
tk.Label(frame, text='Пароль', bg=self.panel, font=('Arial', 11)).pack(anchor='w')
password_entry = tk.Entry(frame, width=35, font=('Arial', 12), show='*')
password_entry.pack(pady=5)
def login():
login_value = login_entry.get().strip()
password_value = password_entry.get().strip()
if not login_value or not password_value:
messagebox.showerror('Ошибка', 'Введите логин и пароль')
return
if check_user(login_value, password_value):
self.current_user = login_value
self.show_main_screen()
else:
messagebox.showerror('Ошибка', 'Неверный логин или пароль')
self.make_button(frame, 'Войти', login).pack(pady=12)
self.make_button(frame, 'Создать профиль', self.show_register).pack(pady=5)
def show_register(self):
self.clear()
frame = tk.Frame(self.root, bg=self.panel, padx=35, pady=35)
frame.place(relx=0.5, rely=0.5, anchor='center')
tk.Label(frame, text='Создание профиля', font=('Arial', 22, 'bold'), bg=self.panel).pack(pady=10)
tk.Label(frame, text='Логин', bg=self.panel, font=('Arial', 11)).pack(anchor='w')
login_entry = tk.Entry(frame, width=35, font=('Arial', 12))
login_entry.pack(pady=5)
tk.Label(frame, text='Пароль', bg=self.panel, font=('Arial', 11)).pack(anchor='w')
password_entry = tk.Entry(frame, width=35, font=('Arial', 12), show='*')
password_entry.pack(pady=5)
def register():
login_value = login_entry.get().strip()
password_value = password_entry.get().strip()
if not login_value or not password_value:
messagebox.showerror('Ошибка', 'Введите логин и пароль')
return
if len(password_value) < 4:
messagebox.showerror('Ошибка', 'Пароль должен быть минимум 4 символа')
return
ok, text = register_user(login_value, password_value)
if ok:
messagebox.showinfo('Готово', text)
self.show_login()
else:
messagebox.showerror('Ошибка', text)
self.make_button(frame, 'Зарегистрироваться', register).pack(pady=12)
self.make_button(frame, 'Назад', self.show_login).pack(pady=5)
def show_main_screen(self):
self.clear()
top = tk.Frame(self.root, bg='#1d3557', height=60)
top.pack(fill='x')
tk.Label(
top,
text=f'Universal Git Analyzer | Пользователь: {self.current_user}',
bg='#1d3557',
fg='white',
font=('Arial', 18, 'bold'),
).pack(side='left', padx=20, pady=15)
tk.Button(top, text='Выйти', command=self.show_login, bg='#e63946', fg='white', relief='flat', font=('Arial', 12)).pack(side='right', padx=20)
content = tk.Frame(self.root, bg=self.bg)
content.pack(fill='both', expand=True, padx=15, pady=15)
left = tk.Frame(content, bg=self.panel, padx=15, pady=15)
left.pack(side='left', fill='y')
right = tk.Frame(content, bg=self.panel, padx=15, pady=15)
right.pack(side='right', fill='both', expand=True, padx=(15, 0))
tk.Label(left, text='Мои репозитории', bg=self.panel, font=('Arial', 22, 'bold')).pack(anchor='w')
repo_listbox = tk.Listbox(left, width=48, height=20, font=('Arial', 12))
repo_listbox.pack(pady=10)
tk.Label(left, text='Новая ссылка', bg=self.panel, font=('Arial', 13)).pack(anchor='w')
repo_entry = tk.Entry(left, width=48, font=('Arial', 12))
repo_entry.pack(pady=5)
result_text = tk.Text(right, width=65, height=28, font=('Consolas', 13), wrap='word')
result_text.pack(fill='both', expand=True)
def refresh_list():
repo_listbox.delete(0, tk.END)
for repo in get_repositories(self.current_user):
repo_listbox.insert(tk.END, repo)
def get_selected_repo():
selection = repo_listbox.curselection()
if not selection:
return None
return repo_listbox.get(selection[0])
def save_repo():
link = repo_entry.get().strip()
if not link:
messagebox.showerror('Ошибка', 'Введите ссылку')
return
if not (link.startswith('https://') or link.startswith('http://') or link.startswith('git@')):
messagebox.showerror('Ошибка', 'Введите нормальную git-ссылку')
return
added = add_repository(self.current_user, link)
if added:
repo_entry.delete(0, tk.END)
refresh_list()
messagebox.showinfo('Готово', 'Ссылка сохранена')
else:
messagebox.showinfo('Информация', 'Эта ссылка уже сохранена')
def remove_repo():
link = get_selected_repo()
if not link:
messagebox.showerror('Ошибка', 'Выберите репозиторий')
return
delete_repository(self.current_user, link)
refresh_list()
result_text.delete('1.0', tk.END)
def analyze_selected():
link = get_selected_repo()
if not link:
messagebox.showerror('Ошибка', 'Выберите репозиторий')
return
result_text.delete('1.0', tk.END)
result_text.insert(tk.END, 'Загрузка данных...\n')
def worker():
try:
info = analyze_repository(link)
self.root.after(0, lambda: show_result(info))
except Exception as e:
self.root.after(0, lambda: show_error(str(e)))
def show_result(info):
result_text.delete('1.0', tk.END)
result_text.insert(tk.END, info)
def show_error(error):
result_text.delete('1.0', tk.END)
messagebox.showerror('Ошибка', f'Не удалось проанализировать репозиторий:\n{error}')
threading.Thread(target=worker, daemon=True).start()
self.make_button(left, 'Сохранить ссылку', save_repo, width=28).pack(pady=5)
self.make_button(left, 'Обновить информацию', analyze_selected, width=28).pack(pady=5)
self.make_button(left, 'Удалить ссылку', remove_repo, width=28).pack(pady=5)
tk.Label(
left,
text='Поддерживаются публичные git-ссылки:\nGitea, GitHub, GitLab, Forgejo и другие.',
bg=self.panel,
fg='#444444',
font=('Arial', 10),
justify='left',
).pack(anchor='w', pady=15)
refresh_list()
if __name__ == '__main__':
GitAnalyzerApp()