mdbq 4.0.119__py3-none-any.whl → 4.0.121__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 mdbq might be problematic. Click here for more details.

mdbq/__version__.py CHANGED
@@ -1 +1 @@
1
- VERSION = '4.0.119'
1
+ VERSION = '4.0.121'
mdbq/auth/auth_backend.py CHANGED
@@ -364,6 +364,49 @@ class StandaloneAuthManager:
364
364
  COLLATE=utf8mb4_0900_ai_ci
365
365
  ''')
366
366
 
367
+ # 用户详细资料表
368
+ cursor.execute('''
369
+ CREATE TABLE IF NOT EXISTS user_profiles (
370
+ id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
371
+ user_id BIGINT UNSIGNED NOT NULL,
372
+ real_name VARCHAR(50) DEFAULT '' COMMENT '真实姓名',
373
+ nickname VARCHAR(50) DEFAULT '' COMMENT '昵称',
374
+ avatar_url VARCHAR(500) DEFAULT '' COMMENT '头像URL',
375
+ phone VARCHAR(20) DEFAULT '' COMMENT '手机号',
376
+ birth_date DATE DEFAULT NULL COMMENT '出生日期',
377
+ gender ENUM('male', 'female', 'other') DEFAULT 'other' COMMENT '性别',
378
+ bio TEXT DEFAULT '' COMMENT '个人简介',
379
+ location VARCHAR(100) DEFAULT '' COMMENT '所在地',
380
+ website VARCHAR(255) DEFAULT '' COMMENT '个人网站',
381
+ company VARCHAR(100) DEFAULT '' COMMENT '公司',
382
+ position VARCHAR(100) DEFAULT '' COMMENT '职位',
383
+ education VARCHAR(255) DEFAULT '' COMMENT '教育背景',
384
+ interests TEXT DEFAULT '' COMMENT '兴趣爱好',
385
+ social_links JSON DEFAULT NULL COMMENT '社交链接',
386
+ privacy_settings JSON DEFAULT NULL COMMENT '隐私设置',
387
+ notification_settings JSON DEFAULT NULL COMMENT '通知设置',
388
+ timezone VARCHAR(50) DEFAULT 'UTC' COMMENT '时区',
389
+ language VARCHAR(10) DEFAULT 'zh-CN' COMMENT '语言',
390
+ theme VARCHAR(20) DEFAULT 'light' COMMENT '主题偏好',
391
+ created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
392
+ updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
393
+
394
+ UNIQUE KEY uk_user_profiles_user_id (user_id),
395
+ KEY idx_user_profiles_real_name (real_name),
396
+ KEY idx_user_profiles_nickname (nickname),
397
+ KEY idx_user_profiles_company (company),
398
+ KEY idx_user_profiles_location (location),
399
+
400
+ CONSTRAINT fk_user_profiles_user_id
401
+ FOREIGN KEY (user_id)
402
+ REFERENCES users (id)
403
+ ON DELETE CASCADE
404
+ ON UPDATE CASCADE
405
+ ) ENGINE=InnoDB
406
+ DEFAULT CHARSET=utf8mb4
407
+ COLLATE=utf8mb4_0900_ai_ci
408
+ ''')
409
+
367
410
  print("数据库表初始化完成")
368
411
 
369
412
  except Exception as e:
@@ -1668,7 +1711,7 @@ class StandaloneAuthManager:
1668
1711
  user_info = cursor.fetchone()
1669
1712
 
1670
1713
  if not user_info:
1671
- return {'error': '用户不存在'}
1714
+ return {'error': '用户不存在', 'user_id': user_id, '数据库查询结果': user_info}
1672
1715
 
1673
1716
  # 获取活跃设备数
1674
1717
  cursor.execute('''
@@ -1922,6 +1965,179 @@ class StandaloneAuthManager:
1922
1965
  cursor.close()
1923
1966
  conn.close()
1924
1967
 
1968
+ def init_user_profile(self, user_id):
1969
+ """为用户初始化默认资料"""
1970
+ conn = self.pool.connection()
1971
+ cursor = conn.cursor()
1972
+
1973
+ try:
1974
+ # 检查是否已存在资料
1975
+ cursor.execute("SELECT id FROM user_profiles WHERE user_id = %s", (user_id,))
1976
+ if cursor.fetchone():
1977
+ return True # 已存在,不需要初始化
1978
+
1979
+ # 创建默认资料
1980
+ cursor.execute('''
1981
+ INSERT INTO user_profiles (
1982
+ user_id, privacy_settings, social_links, notification_settings
1983
+ ) VALUES (%s, %s, %s, %s)
1984
+ ''', (
1985
+ user_id,
1986
+ json.dumps({
1987
+ "profile_visibility": "public",
1988
+ "contact_visibility": "registered",
1989
+ "activity_visibility": "friends"
1990
+ }),
1991
+ json.dumps({
1992
+ "github": "",
1993
+ "linkedin": "",
1994
+ "twitter": "",
1995
+ "personal_site": ""
1996
+ }),
1997
+ json.dumps({
1998
+ "email_notifications": True,
1999
+ "login_alerts": True,
2000
+ "security_updates": True
2001
+ })
2002
+ ))
2003
+
2004
+ return True
2005
+
2006
+ except Exception as e:
2007
+ print(f"初始化用户资料失败: {str(e)}")
2008
+ return False
2009
+ finally:
2010
+ cursor.close()
2011
+ conn.close()
2012
+
2013
+ def get_user_profile(self, user_id):
2014
+ """获取用户详细资料"""
2015
+ conn = self.pool.connection()
2016
+ cursor = conn.cursor()
2017
+
2018
+ try:
2019
+ # 获取用户基本信息
2020
+ cursor.execute('''
2021
+ SELECT u.id, u.username, u.email, u.role, u.permissions, u.created_at, u.last_login,
2022
+ p.real_name, p.nickname, p.avatar_url, p.phone, p.birth_date, p.gender,
2023
+ p.bio, p.location, p.website, p.company, p.position, p.education,
2024
+ p.interests, p.social_links, p.privacy_settings, p.notification_settings,
2025
+ p.timezone, p.language, p.theme, p.updated_at as profile_updated_at
2026
+ FROM users u
2027
+ LEFT JOIN user_profiles p ON u.id = p.user_id
2028
+ WHERE u.id = %s
2029
+ ''', (user_id,))
2030
+
2031
+ result = cursor.fetchone()
2032
+
2033
+ if not result:
2034
+ return None
2035
+
2036
+ # 如果用户资料不存在,初始化一个
2037
+ if not result['real_name'] and not result['nickname']:
2038
+ self.init_user_profile(user_id)
2039
+ # 重新查询
2040
+ return self.get_user_profile(user_id)
2041
+
2042
+ profile = {
2043
+ 'id': result['id'],
2044
+ 'username': result['username'],
2045
+ 'email': result['email'],
2046
+ 'role': result['role'],
2047
+ 'permissions': self._safe_json_parse(result['permissions']),
2048
+ 'created_at': result['created_at'].isoformat() if result['created_at'] else None,
2049
+ 'last_login': result['last_login'].isoformat() if result['last_login'] else None,
2050
+ 'real_name': result['real_name'] or '',
2051
+ 'nickname': result['nickname'] or '',
2052
+ 'avatar_url': result['avatar_url'] or '',
2053
+ 'phone': result['phone'] or '',
2054
+ 'birth_date': result['birth_date'].isoformat() if result['birth_date'] else None,
2055
+ 'gender': result['gender'] or 'other',
2056
+ 'bio': result['bio'] or '',
2057
+ 'location': result['location'] or '',
2058
+ 'website': result['website'] or '',
2059
+ 'company': result['company'] or '',
2060
+ 'position': result['position'] or '',
2061
+ 'education': result['education'] or '',
2062
+ 'interests': result['interests'] or '',
2063
+ 'social_links': self._safe_json_parse(result['social_links']) or {},
2064
+ 'privacy_settings': self._safe_json_parse(result['privacy_settings']) or {},
2065
+ 'notification_settings': self._safe_json_parse(result['notification_settings']) or {},
2066
+ 'timezone': result['timezone'] or 'UTC',
2067
+ 'language': result['language'] or 'zh-CN',
2068
+ 'theme': result['theme'] or 'light',
2069
+ 'profile_updated_at': result['profile_updated_at'].isoformat() if result['profile_updated_at'] else None
2070
+ }
2071
+
2072
+ return profile
2073
+
2074
+ except Exception as e:
2075
+ print(f"获取用户资料失败: {str(e)}")
2076
+ return None
2077
+ finally:
2078
+ cursor.close()
2079
+ conn.close()
2080
+
2081
+ def update_user_profile(self, user_id, profile_data):
2082
+ """更新用户详细资料"""
2083
+ conn = self.pool.connection()
2084
+ cursor = conn.cursor()
2085
+
2086
+ try:
2087
+ # 先确保用户资料记录存在
2088
+ cursor.execute("SELECT id FROM user_profiles WHERE user_id = %s", (user_id,))
2089
+ if not cursor.fetchone():
2090
+ self.init_user_profile(user_id)
2091
+
2092
+ # 可更新的字段
2093
+ updatable_fields = [
2094
+ 'real_name', 'nickname', 'avatar_url', 'phone', 'birth_date', 'gender',
2095
+ 'bio', 'location', 'website', 'company', 'position', 'education',
2096
+ 'interests', 'timezone', 'language', 'theme'
2097
+ ]
2098
+
2099
+ # JSON字段需要特殊处理
2100
+ json_fields = ['social_links', 'privacy_settings', 'notification_settings']
2101
+
2102
+ update_fields = []
2103
+ update_values = []
2104
+
2105
+ # 处理普通字段
2106
+ for field in updatable_fields:
2107
+ if field in profile_data:
2108
+ update_fields.append(f"{field} = %s")
2109
+ update_values.append(profile_data[field])
2110
+
2111
+ # 处理JSON字段
2112
+ for field in json_fields:
2113
+ if field in profile_data:
2114
+ update_fields.append(f"{field} = %s")
2115
+ update_values.append(json.dumps(profile_data[field]))
2116
+
2117
+ if not update_fields:
2118
+ return {'success': True, 'message': '没有需要更新的字段'}
2119
+
2120
+ # 执行更新
2121
+ update_sql = f'''
2122
+ UPDATE user_profiles
2123
+ SET {', '.join(update_fields)}
2124
+ WHERE user_id = %s
2125
+ '''
2126
+ update_values.append(user_id)
2127
+
2128
+ cursor.execute(update_sql, update_values)
2129
+
2130
+ if cursor.rowcount > 0:
2131
+ return {'success': True, 'message': '用户资料更新成功'}
2132
+ else:
2133
+ return {'success': False, 'message': '用户资料更新失败'}
2134
+
2135
+ except Exception as e:
2136
+ return {'success': False, 'message': f'用户资料更新失败: {str(e)}'}
2137
+ finally:
2138
+ cursor.close()
2139
+ conn.close()
2140
+
1925
2141
 
1926
2142
  # Flask集成装饰器
1927
2143
  def require_auth(auth_manager):
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.2
2
2
  Name: mdbq
3
- Version: 4.0.119
3
+ Version: 4.0.121
4
4
  Home-page: https://pypi.org/project/mdbq
5
5
  Author: xigua,
6
6
  Author-email: 2587125111@qq.com
@@ -1,7 +1,7 @@
1
1
  mdbq/__init__.py,sha256=Il5Q9ATdX8yXqVxtP_nYqUhExzxPC_qk_WXQ_4h0exg,16
2
- mdbq/__version__.py,sha256=tD5dnIydHX4mck7Xur3Z8cEjpyIbm2VHwhh8vKAXlCc,19
2
+ mdbq/__version__.py,sha256=nmzCI2UH3xZCIyCqmNK90zL0q-YoaXKjbOby764YqjA,19
3
3
  mdbq/auth/__init__.py,sha256=pnPMAt63sh1B6kEvmutUuro46zVf2v2YDAG7q-jV_To,24
4
- mdbq/auth/auth_backend.py,sha256=-6PyJNwGnZd8BwFGnOn3396tj2fxy1uP5K1f0gC0zow,86562
4
+ mdbq/auth/auth_backend.py,sha256=zotA9q_Y6VM-jOtVb0h_-8Vtyi5s7vpbox2ccd1SEiE,96400
5
5
  mdbq/auth/rate_limiter.py,sha256=1m_Paxp8pDNpmyoFGRpFMVOJpbmeIvfVcfiQ2oH72qM,32850
6
6
  mdbq/js/__init__.py,sha256=hpMi3_ZKwIWkzc0LnKL-SY9AS-7PYFHq0izYTgEvxjc,30
7
7
  mdbq/js/jc.py,sha256=6Rgf1WqaJJ1oevpn-pt08gXKbX5hjoQaV6uZGCAGbYw,13177
@@ -34,7 +34,7 @@ mdbq/route/routes.py,sha256=QVGfTvDgu0CpcKCvk1ra74H8uojgqTLUav1fnVAqLEA,29433
34
34
  mdbq/selenium/__init__.py,sha256=AKzeEceqZyvqn2dEDoJSzDQnbuENkJSHAlbHAD0u0ZI,10
35
35
  mdbq/selenium/get_driver.py,sha256=1NTlVUE6QsyjTrVVVqTO2LOnYf578ccFWlWnvIXGtic,20903
36
36
  mdbq/spider/__init__.py,sha256=RBMFXGy_jd1HXZhngB2T2XTvJqki8P_Fr-pBcwijnew,18
37
- mdbq-4.0.119.dist-info/METADATA,sha256=dQKXtv0p3Y9TizdOrOgnSzo7Zc2Eci8BSQLi5b0F44c,365
38
- mdbq-4.0.119.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
39
- mdbq-4.0.119.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
40
- mdbq-4.0.119.dist-info/RECORD,,
37
+ mdbq-4.0.121.dist-info/METADATA,sha256=vw2V94FnE3qWlnI0zhtdtSKouGg2TwVo4e05Oqs87d8,365
38
+ mdbq-4.0.121.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
39
+ mdbq-4.0.121.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
40
+ mdbq-4.0.121.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (75.8.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5