Skip to content

Commit cd76119

Browse files
committed
feat: Реализовал систему учётных записей
1 parent 9e2f35b commit cd76119

File tree

6 files changed

+559
-68
lines changed

6 files changed

+559
-68
lines changed

db.py

Lines changed: 202 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,128 @@
1+
import hashlib
12
import sqlite3
23

34
from utils import get_data_path
45

56

7+
def hash_password(password: str) -> str:
8+
return hashlib.sha256(password.encode()).hexdigest()
9+
10+
11+
class UserManager:
12+
def __init__(self, db_path):
13+
self.db_path = db_path
14+
self._current_user_id = None
15+
self._current_user_login = None
16+
self._load_session()
17+
18+
def register_user(self, login: str, password: str) -> bool:
19+
20+
if self.user_exists(login):
21+
return False
22+
23+
conn = sqlite3.connect(self.db_path)
24+
cursor = conn.cursor()
25+
try:
26+
hashed_password = hash_password(password)
27+
cursor.execute(
28+
"INSERT INTO Users (login, password) VALUES (?, ?)",
29+
(login, hashed_password),
30+
)
31+
user_id = cursor.lastrowid
32+
33+
cursor.execute(
34+
"INSERT INTO Categories (name, user_id) VALUES (?, ?)",
35+
("Все", user_id),
36+
)
37+
38+
conn.commit()
39+
return True
40+
except Exception as e:
41+
print(f"Ошибка при регистрации пользователя: {e}")
42+
return False
43+
finally:
44+
conn.close()
45+
46+
def login_user(self, login: str, password: str) -> bool:
47+
conn = sqlite3.connect(self.db_path)
48+
cursor = conn.cursor()
49+
try:
50+
hashed_password = hash_password(password)
51+
cursor.execute(
52+
"SELECT id, login FROM Users WHERE login = ? AND password = ?",
53+
(login, hashed_password),
54+
)
55+
user = cursor.fetchone()
56+
if user:
57+
self._current_user_id = user[0]
58+
self._current_user_login = user[1]
59+
self._save_session()
60+
return True
61+
return False
62+
finally:
63+
conn.close()
64+
65+
def user_exists(self, login: str) -> bool:
66+
conn = sqlite3.connect(self.db_path)
67+
cursor = conn.cursor()
68+
try:
69+
cursor.execute(
70+
"SELECT COUNT(*) FROM Users WHERE login = ?", (login,)
71+
)
72+
count = cursor.fetchone()[0]
73+
return count > 0
74+
finally:
75+
conn.close()
76+
77+
def get_current_user_id(self) -> int | None:
78+
if not self._current_user_id:
79+
self._load_session()
80+
return self._current_user_id
81+
82+
def get_current_user_login(self) -> str | None:
83+
if not self._current_user_login:
84+
self._load_session()
85+
return self._current_user_login
86+
87+
def is_authenticated(self) -> bool:
88+
return bool(self.get_current_user_id())
89+
90+
def logout(self):
91+
self._current_user_id = None
92+
self._current_user_login = None
93+
self._delete_session()
94+
95+
def _save_session(self):
96+
from utils import data_manager
97+
98+
if (
99+
self._current_user_id is not None
100+
and self._current_user_login is not None
101+
):
102+
data_manager.session.save_session(
103+
self._current_user_id, self._current_user_login
104+
)
105+
else:
106+
data_manager.session.clear_session()
107+
108+
def _load_session(self):
109+
from utils import data_manager
110+
111+
self._current_user_id, self._current_user_login = (
112+
data_manager.session.load_session()
113+
)
114+
115+
def _delete_session(self):
116+
from utils import data_manager
117+
118+
data_manager.session.clear_session()
119+
120+
6121
class Database:
7122
def __init__(self):
8123
self.data_path = get_data_path()
9124
self.db_path = self.data_path / "games.db"
125+
self.users = UserManager(self.db_path)
10126
self.create_tables()
11127

12128
def get_connection(self):
@@ -19,7 +135,10 @@ def create_tables(self):
19135
cursor.execute(
20136
"""CREATE TABLE IF NOT EXISTS Categories (
21137
id INTEGER PRIMARY KEY AUTOINCREMENT,
22-
name TEXT NOT NULL UNIQUE
138+
name TEXT NOT NULL,
139+
user_id INTEGER NOT NULL,
140+
UNIQUE(name, user_id),
141+
FOREIGN KEY (user_id) REFERENCES Users (id)
23142
)"""
24143
)
25144

@@ -29,12 +148,19 @@ def create_tables(self):
29148
name TEXT NOT NULL UNIQUE,
30149
path TEXT NOT NULL UNIQUE,
31150
category_id INTEGER NOT NULL,
32-
FOREIGN KEY (category_id) REFERENCES Categories(id)
151+
user_id INTEGER NOT NULL,
152+
FOREIGN KEY (category_id) REFERENCES Categories(id),
153+
FOREIGN KEY (user_id) REFERENCES Users(id)
33154
)"""
34155
)
35156

36157
cursor.execute(
37-
"INSERT OR IGNORE INTO Categories (name) VALUES (?)", ("Все",)
158+
"""
159+
CREATE TABLE IF NOT EXISTS Users (
160+
id INTEGER PRIMARY KEY AUTOINCREMENT,
161+
login TEXT NOT NULL UNIQUE,
162+
password TEXT NOT NULL
163+
)"""
38164
)
39165

40166
conn.commit()
@@ -43,20 +169,28 @@ def create_tables(self):
43169
def check_unique(self, select_from, where_value, parameter):
44170
conn = self.get_connection()
45171
cursor = conn.cursor()
46-
cursor.execute(
47-
f"SELECT COUNT(*) FROM {select_from} WHERE {where_value} = ?",
48-
(parameter,),
49-
)
172+
if select_from in ["Games", "Categories"]:
173+
user_id = self.users.get_current_user_id()
174+
cursor.execute(
175+
f"SELECT COUNT(*) FROM {select_from} WHERE {where_value} = ? AND user_id = ?",
176+
(parameter, user_id),
177+
)
178+
else:
179+
cursor.execute(
180+
f"SELECT COUNT(*) FROM {select_from} WHERE {where_value} = ?",
181+
(parameter,),
182+
)
50183
count = cursor.fetchone()[0]
51184
return count == 0
52185

53186
def insert_game(self, name, game_path, category_id):
54187
conn = self.get_connection()
55188
cursor = conn.cursor()
56189
try:
190+
user_id = self.users.get_current_user_id()
57191
cursor.execute(
58-
"INSERT INTO Games (name, path, category_id) VALUES (?, ?, ?)",
59-
(name, game_path, category_id),
192+
"INSERT INTO Games (name, path, category_id, user_id) VALUES (?, ?, ?, ?)",
193+
(name, game_path, category_id, user_id),
60194
)
61195
conn.commit()
62196
except Exception as e:
@@ -68,13 +202,24 @@ def insert_category(self, name):
68202
conn = self.get_connection()
69203
cursor = conn.cursor()
70204
try:
205+
user_id = self.users.get_current_user_id()
206+
207+
cursor.execute(
208+
"SELECT COUNT(*) FROM Categories WHERE name = ? AND user_id = ?",
209+
(name, user_id),
210+
)
211+
if cursor.fetchone()[0] > 0:
212+
return False
213+
71214
cursor.execute(
72-
"INSERT INTO Categories (name) VALUES (?)",
73-
(name,),
215+
"INSERT INTO Categories (name, user_id) VALUES (?, ?)",
216+
(name, user_id),
74217
)
75218
conn.commit()
219+
return True
76220
except Exception as e:
77221
print(f"Ошибка при добавлении категории: {e}")
222+
return False
78223
finally:
79224
conn.close()
80225

@@ -95,8 +240,10 @@ def delete(self, select_from, where_value, parameter):
95240
def get_games_by_category(self, category_id):
96241
conn = self.get_connection()
97242
cursor = conn.cursor()
243+
user_id = self.users.get_current_user_id()
98244
cursor.execute(
99-
"SELECT * FROM Games WHERE category_id = ?", (category_id,)
245+
"SELECT * FROM Games WHERE category_id = ? AND user_id = ?",
246+
(category_id, user_id),
100247
)
101248
games = cursor.fetchall()
102249
conn.close()
@@ -106,9 +253,10 @@ def edit_games_category(self, category_id_old, category_id_new):
106253
conn = self.get_connection()
107254
cursor = conn.cursor()
108255
try:
256+
user_id = self.users.get_current_user_id()
109257
cursor.execute(
110-
"UPDATE Games SET category_id = ? WHERE category_id = ?",
111-
(category_id_new, category_id_old),
258+
"UPDATE Games SET category_id = ? WHERE category_id = ? AND user_id = ?",
259+
(category_id_new, category_id_old, user_id),
112260
)
113261
conn.commit()
114262
except Exception as e:
@@ -120,22 +268,28 @@ def check_category_id_is_valid(self):
120268
conn = self.get_connection()
121269
cursor = conn.cursor()
122270
try:
123-
cursor.execute("SELECT id FROM Categories")
271+
user_id = self.users.get_current_user_id()
272+
cursor.execute(
273+
"SELECT id FROM Categories WHERE user_id = ?", (user_id,)
274+
)
124275
valid_category_ids = {row[0] for row in cursor.fetchall()}
125276

277+
if not valid_category_ids:
278+
return
279+
126280
cursor.execute(
127-
"SELECT id, name, category_id FROM Games WHERE category_id NOT IN ({})".format(
281+
"SELECT id, name, category_id FROM Games WHERE category_id NOT IN ({}) AND user_id = ?".format(
128282
",".join("?" for _ in valid_category_ids)
129283
),
130-
list(valid_category_ids),
284+
list(valid_category_ids) + [user_id],
131285
)
132286

133287
invalid_games = cursor.fetchall()
134288

135289
for game_id, game_name, old_category_id in invalid_games:
136290
cursor.execute(
137-
"UPDATE Games SET category_id = ? WHERE id = ?",
138-
(1, game_id),
291+
"UPDATE Games SET category_id = ? WHERE id = ? AND user_id = ?",
292+
(1, game_id, user_id),
139293
)
140294

141295
conn.commit()
@@ -147,31 +301,47 @@ def check_category_id_is_valid(self):
147301
def get_categories(self):
148302
conn = self.get_connection()
149303
cursor = conn.cursor()
150-
cursor.execute("""SELECT name FROM Categories""")
304+
user_id = self.users.get_current_user_id()
305+
cursor.execute(
306+
"""SELECT name FROM Categories
307+
WHERE user_id = ?
308+
ORDER BY CASE name WHEN 'Все' THEN 0 ELSE 1 END, name""",
309+
(user_id,),
310+
)
151311
categories = cursor.fetchall()
152312
conn.close()
153313
return categories
154314

155315
def get_category_name_by_id(self, _id):
156316
conn = self.get_connection()
157317
cursor = conn.cursor()
158-
cursor.execute("SELECT name FROM Categories WHERE id = ?", (_id,))
318+
user_id = self.users.get_current_user_id()
319+
cursor.execute(
320+
"SELECT name FROM Categories WHERE id = ? AND user_id = ?",
321+
(_id, user_id),
322+
)
159323
name = cursor.fetchone()[0]
160324
conn.close()
161325
return name
162326

163327
def get_category_id_by_name(self, name):
164328
conn = self.get_connection()
165329
cursor = conn.cursor()
166-
cursor.execute("SELECT id FROM Categories WHERE name = ?", (name,))
167-
_id = cursor.fetchone()[0]
330+
user_id = self.users.get_current_user_id()
331+
cursor.execute(
332+
"SELECT id FROM Categories WHERE name = ? AND user_id = ?",
333+
(name, user_id),
334+
)
335+
result = cursor.fetchone()
336+
_id = result[0] if result else None
168337
conn.close()
169338
return _id
170339

171340
def get_games(self):
172341
conn = self.get_connection()
173342
cursor = conn.cursor()
174-
cursor.execute("SELECT name FROM Games")
343+
user_id = self.users.get_current_user_id()
344+
cursor.execute("SELECT name FROM Games WHERE user_id = ?", (user_id,))
175345
games = cursor.fetchall()
176346
conn.close()
177347

@@ -181,7 +351,11 @@ def get_games(self):
181351
def get_game(self, name):
182352
conn = self.get_connection()
183353
cursor = conn.cursor()
184-
cursor.execute("SELECT * FROM Games WHERE name = ?", (name,))
354+
user_id = self.users.get_current_user_id()
355+
cursor.execute(
356+
"SELECT * FROM Games WHERE name = ? AND user_id = ?",
357+
(name, user_id),
358+
)
185359
row = cursor.fetchone()
186360
conn.close()
187361
return row
@@ -190,14 +364,14 @@ def update_game(self, old_name, new_name, category_id):
190364
conn = self.get_connection()
191365
cursor = conn.cursor()
192366
try:
367+
user_id = self.users.get_current_user_id()
193368
cursor.execute(
194-
"UPDATE Games SET name = ?, category_id = ? WHERE name = ?",
195-
(new_name, category_id, old_name),
369+
"UPDATE Games SET name = ?, category_id = ? WHERE name = ? AND user_id = ?",
370+
(new_name, category_id, old_name, user_id),
196371
)
197372
conn.commit()
198373
except Exception as e:
199374
print(str(e))
200-
201375
finally:
202376
conn.close()
203377

0 commit comments

Comments
 (0)