matplobbot-shared 0.1.25__py3-none-any.whl → 0.1.26__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of matplobbot-shared might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: matplobbot-shared
3
- Version: 0.1.25
3
+ Version: 0.1.26
4
4
  Summary: Shared library for the Matplobbot ecosystem (database, services, i18n).
5
5
  Author: Ackrome
6
6
  Author-email: ivansergeyevich@gmail.com
@@ -1,10 +1,10 @@
1
1
  shared_lib/__init__.py,sha256=Wxuw1wbvCOsKqs6WfIQ05cx_vndhPs6rH2krMatFRqA,45
2
- shared_lib/database.py,sha256=ZAsi33HNxc3exhTCMgqvaEoqDqLq28k4c1H5GFGGcY4,13066
2
+ shared_lib/database.py,sha256=CjjJ9HX_70IXOJ6aIS8xoD63Srj3Y-WHUqZ0zPCJsYc,15554
3
3
  shared_lib/i18n.py,sha256=VBWQWVF-k_HDiidYo_RUPyUCM7oL897z5hOw9jvOoYY,1762
4
4
  shared_lib/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  shared_lib/services/schedule_service.py,sha256=tKXgwZQWeaagQeqG_tKP2gLflWo_6kxKZOhW9PFvbK4,1835
6
6
  shared_lib/services/university_api.py,sha256=Ui-zjfKOHCCf2Imh8CNtVOWegwuep7IB8gO9IKNUrrE,1898
7
- matplobbot_shared-0.1.25.dist-info/METADATA,sha256=s2XjI37wwrFkMQbS7SX1o4Rq9YwbTP9PLAilcCRK7DE,395
8
- matplobbot_shared-0.1.25.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
- matplobbot_shared-0.1.25.dist-info/top_level.txt,sha256=L8mrC50YWCe19jmh_zrUZFvXSkhsnES5K6y027G1838,11
10
- matplobbot_shared-0.1.25.dist-info/RECORD,,
7
+ matplobbot_shared-0.1.26.dist-info/METADATA,sha256=SEK0yxxYSavWzGQSx2C9EcgYaWdNL9TB3sdI2orLF8k,395
8
+ matplobbot_shared-0.1.26.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
+ matplobbot_shared-0.1.26.dist-info/top_level.txt,sha256=L8mrC50YWCe19jmh_zrUZFvXSkhsnES5K6y027G1838,11
10
+ matplobbot_shared-0.1.26.dist-info/RECORD,,
shared_lib/database.py CHANGED
@@ -282,4 +282,63 @@ async def get_user_profile_data_from_db(db_conn, user_id: int, page: int = 1, pa
282
282
  user_details = {k: first_row[k] for k in ["user_id", "full_name", "username", "avatar_pic_url"]}
283
283
  actions = [dict(r) for r in rows if r["action_id"] is not None]
284
284
 
285
- return {"user_details": user_details, "actions": actions, "total_actions": first_row["total_actions"]}
285
+ return {"user_details": user_details, "actions": actions, "total_actions": first_row["total_actions"]}
286
+
287
+
288
+ async def get_users_for_action(db_conn, action_type: str, action_details: str, page: int = 1, page_size: int = 15, sort_by: str = 'full_name', sort_order: str = 'asc'):
289
+ """Извлекает пагинированный список уникальных пользователей, совершивших определенное действие."""
290
+ # Note: action_type for messages is 'text_message' in the DB
291
+ db_action_type = 'text_message' if action_type == 'message' else action_type
292
+ offset = (page - 1) * page_size
293
+
294
+ # --- Безопасная сортировка ---
295
+ allowed_sort_columns = ['user_id', 'full_name', 'username'] # These are u columns
296
+ if sort_by not in allowed_sort_columns:
297
+ sort_by = 'full_name' # Значение по умолчанию
298
+ sort_order = 'DESC' if sort_order.lower() == 'desc' else 'ASC' # Безопасное определение порядка
299
+ order_by_clause = f"ORDER BY u.{sort_by} {sort_order}"
300
+
301
+ # Query for total count of distinct users
302
+ count_query = """
303
+ SELECT COUNT(DISTINCT u.user_id)
304
+ FROM users u
305
+ JOIN user_actions ua ON u.user_id = ua.user_id
306
+ WHERE ua.action_type = $1 AND ua.action_details = $2;
307
+ """
308
+ total_users = await db_conn.fetchval(count_query, db_action_type, action_details)
309
+
310
+ # Query for the paginated list of users
311
+ users_query = f"""
312
+ SELECT DISTINCT
313
+ u.user_id,
314
+ u.full_name,
315
+ COALESCE(u.username, 'Нет username') AS username
316
+ FROM users u
317
+ JOIN user_actions ua ON u.user_id = ua.user_id
318
+ WHERE ua.action_type = $1 AND ua.action_details = $2
319
+ {order_by_clause}
320
+ LIMIT $3 OFFSET $4;
321
+ """
322
+ rows = await db_conn.fetch(users_query, db_action_type, action_details, page_size, offset)
323
+ users = [dict(row) for row in rows]
324
+
325
+ return {
326
+ "users": users,
327
+ "total_users": total_users
328
+ }
329
+
330
+
331
+ async def get_all_user_actions(db_conn, user_id: int):
332
+ """Извлекает ВСЕ действия для указанного пользователя без пагинации."""
333
+ query = """
334
+ SELECT
335
+ id,
336
+ action_type,
337
+ action_details,
338
+ TO_CHAR(timestamp, 'YYYY-MM-DD HH24:MI:SS') AS timestamp
339
+ FROM user_actions
340
+ WHERE user_id = $1
341
+ ORDER BY timestamp DESC;
342
+ """
343
+ rows = await db_conn.fetch(query, user_id)
344
+ return [dict(row) for row in rows]