mdbq 4.0.120__tar.gz → 4.0.122__tar.gz

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.

Files changed (45) hide show
  1. {mdbq-4.0.120 → mdbq-4.0.122}/PKG-INFO +2 -2
  2. mdbq-4.0.122/mdbq/__version__.py +1 -0
  3. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/auth/auth_backend.py +215 -1
  4. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq.egg-info/PKG-INFO +2 -2
  5. mdbq-4.0.120/mdbq/__version__.py +0 -1
  6. {mdbq-4.0.120 → mdbq-4.0.122}/README.txt +0 -0
  7. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/__init__.py +0 -0
  8. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/auth/__init__.py +0 -0
  9. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/auth/rate_limiter.py +0 -0
  10. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/js/__init__.py +0 -0
  11. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/js/jc.py +0 -0
  12. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/log/__init__.py +0 -0
  13. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/log/mylogger.py +0 -0
  14. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/myconf/__init__.py +0 -0
  15. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/myconf/myconf.py +0 -0
  16. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/mysql/__init__.py +0 -0
  17. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/mysql/deduplicator.py +0 -0
  18. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/mysql/mysql.py +0 -0
  19. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/mysql/s_query.py +0 -0
  20. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/mysql/unique_.py +0 -0
  21. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/mysql/uploader.py +0 -0
  22. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/other/__init__.py +0 -0
  23. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/other/download_sku_picture.py +0 -0
  24. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/other/error_handler.py +0 -0
  25. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/other/otk.py +0 -0
  26. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/other/pov_city.py +0 -0
  27. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/other/ua_sj.py +0 -0
  28. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/pbix/__init__.py +0 -0
  29. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/pbix/pbix_refresh.py +0 -0
  30. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/pbix/refresh_all.py +0 -0
  31. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/redis/__init__.py +0 -0
  32. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/redis/getredis.py +0 -0
  33. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/redis/redis_cache.py +0 -0
  34. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/route/__init__.py +0 -0
  35. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/route/analytics.py +0 -0
  36. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/route/monitor.py +0 -0
  37. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/route/routes.py +0 -0
  38. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/selenium/__init__.py +0 -0
  39. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/selenium/get_driver.py +0 -0
  40. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/spider/__init__.py +0 -0
  41. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq.egg-info/SOURCES.txt +0 -0
  42. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq.egg-info/dependency_links.txt +0 -0
  43. {mdbq-4.0.120 → mdbq-4.0.122}/mdbq.egg-info/top_level.txt +0 -0
  44. {mdbq-4.0.120 → mdbq-4.0.122}/setup.cfg +0 -0
  45. {mdbq-4.0.120 → mdbq-4.0.122}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.2
2
2
  Name: mdbq
3
- Version: 4.0.120
3
+ Version: 4.0.122
4
4
  Home-page: https://pypi.org/project/mdbq
5
5
  Author: xigua,
6
6
  Author-email: 2587125111@qq.com
@@ -0,0 +1 @@
1
+ VERSION = '4.0.122'
@@ -364,7 +364,48 @@ class StandaloneAuthManager:
364
364
  COLLATE=utf8mb4_0900_ai_ci
365
365
  ''')
366
366
 
367
- print("数据库表初始化完成")
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 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 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
+ ''')
368
409
 
369
410
  except Exception as e:
370
411
  print(f"数据库表创建失败: {e}")
@@ -1922,6 +1963,179 @@ class StandaloneAuthManager:
1922
1963
  cursor.close()
1923
1964
  conn.close()
1924
1965
 
1966
+ def init_user_profile(self, user_id):
1967
+ """为用户初始化默认资料"""
1968
+ conn = self.pool.connection()
1969
+ cursor = conn.cursor()
1970
+
1971
+ try:
1972
+ # 检查是否已存在资料
1973
+ cursor.execute("SELECT id FROM user_profiles WHERE user_id = %s", (user_id,))
1974
+ if cursor.fetchone():
1975
+ return True # 已存在,不需要初始化
1976
+
1977
+ # 创建默认资料
1978
+ cursor.execute('''
1979
+ INSERT INTO user_profiles (
1980
+ user_id, privacy_settings, social_links, notification_settings
1981
+ ) VALUES (%s, %s, %s, %s)
1982
+ ''', (
1983
+ user_id,
1984
+ json.dumps({
1985
+ "profile_visibility": "public",
1986
+ "contact_visibility": "registered",
1987
+ "activity_visibility": "friends"
1988
+ }),
1989
+ json.dumps({
1990
+ "github": "",
1991
+ "linkedin": "",
1992
+ "twitter": "",
1993
+ "personal_site": ""
1994
+ }),
1995
+ json.dumps({
1996
+ "email_notifications": True,
1997
+ "login_alerts": True,
1998
+ "security_updates": True
1999
+ })
2000
+ ))
2001
+
2002
+ return True
2003
+
2004
+ except Exception as e:
2005
+ print(f"初始化用户资料失败: {str(e)}")
2006
+ return False
2007
+ finally:
2008
+ cursor.close()
2009
+ conn.close()
2010
+
2011
+ def get_user_profile(self, user_id):
2012
+ """获取用户详细资料"""
2013
+ conn = self.pool.connection()
2014
+ cursor = conn.cursor()
2015
+
2016
+ try:
2017
+ # 获取用户基本信息
2018
+ cursor.execute('''
2019
+ SELECT u.id, u.username, u.email, u.role, u.permissions, u.created_at, u.last_login,
2020
+ p.real_name, p.nickname, p.avatar_url, p.phone, p.birth_date, p.gender,
2021
+ p.bio, p.location, p.website, p.company, p.position, p.education,
2022
+ p.interests, p.social_links, p.privacy_settings, p.notification_settings,
2023
+ p.timezone, p.language, p.theme, p.updated_at as profile_updated_at
2024
+ FROM users u
2025
+ LEFT JOIN user_profiles p ON u.id = p.user_id
2026
+ WHERE u.id = %s
2027
+ ''', (user_id,))
2028
+
2029
+ result = cursor.fetchone()
2030
+
2031
+ if not result:
2032
+ return None
2033
+
2034
+ # 如果用户资料不存在,初始化一个
2035
+ if not result['real_name'] and not result['nickname']:
2036
+ self.init_user_profile(user_id)
2037
+ # 重新查询
2038
+ return self.get_user_profile(user_id)
2039
+
2040
+ profile = {
2041
+ 'id': result['id'],
2042
+ 'username': result['username'],
2043
+ 'email': result['email'],
2044
+ 'role': result['role'],
2045
+ 'permissions': self._safe_json_parse(result['permissions']),
2046
+ 'created_at': result['created_at'].isoformat() if result['created_at'] else None,
2047
+ 'last_login': result['last_login'].isoformat() if result['last_login'] else None,
2048
+ 'real_name': result['real_name'] or '',
2049
+ 'nickname': result['nickname'] or '',
2050
+ 'avatar_url': result['avatar_url'] or '',
2051
+ 'phone': result['phone'] or '',
2052
+ 'birth_date': result['birth_date'].isoformat() if result['birth_date'] else None,
2053
+ 'gender': result['gender'] or 'other',
2054
+ 'bio': result['bio'] or '',
2055
+ 'location': result['location'] or '',
2056
+ 'website': result['website'] or '',
2057
+ 'company': result['company'] or '',
2058
+ 'position': result['position'] or '',
2059
+ 'education': result['education'] or '',
2060
+ 'interests': result['interests'] or '',
2061
+ 'social_links': self._safe_json_parse(result['social_links']) or {},
2062
+ 'privacy_settings': self._safe_json_parse(result['privacy_settings']) or {},
2063
+ 'notification_settings': self._safe_json_parse(result['notification_settings']) or {},
2064
+ 'timezone': result['timezone'] or 'UTC',
2065
+ 'language': result['language'] or 'zh-CN',
2066
+ 'theme': result['theme'] or 'light',
2067
+ 'profile_updated_at': result['profile_updated_at'].isoformat() if result['profile_updated_at'] else None
2068
+ }
2069
+
2070
+ return profile
2071
+
2072
+ except Exception as e:
2073
+ print(f"获取用户资料失败: {str(e)}")
2074
+ return None
2075
+ finally:
2076
+ cursor.close()
2077
+ conn.close()
2078
+
2079
+ def update_user_profile(self, user_id, profile_data):
2080
+ """更新用户详细资料"""
2081
+ conn = self.pool.connection()
2082
+ cursor = conn.cursor()
2083
+
2084
+ try:
2085
+ # 先确保用户资料记录存在
2086
+ cursor.execute("SELECT id FROM user_profiles WHERE user_id = %s", (user_id,))
2087
+ if not cursor.fetchone():
2088
+ self.init_user_profile(user_id)
2089
+
2090
+ # 可更新的字段
2091
+ updatable_fields = [
2092
+ 'real_name', 'nickname', 'avatar_url', 'phone', 'birth_date', 'gender',
2093
+ 'bio', 'location', 'website', 'company', 'position', 'education',
2094
+ 'interests', 'timezone', 'language', 'theme'
2095
+ ]
2096
+
2097
+ # JSON字段需要特殊处理
2098
+ json_fields = ['social_links', 'privacy_settings', 'notification_settings']
2099
+
2100
+ update_fields = []
2101
+ update_values = []
2102
+
2103
+ # 处理普通字段
2104
+ for field in updatable_fields:
2105
+ if field in profile_data:
2106
+ update_fields.append(f"{field} = %s")
2107
+ update_values.append(profile_data[field])
2108
+
2109
+ # 处理JSON字段
2110
+ for field in json_fields:
2111
+ if field in profile_data:
2112
+ update_fields.append(f"{field} = %s")
2113
+ update_values.append(json.dumps(profile_data[field]))
2114
+
2115
+ if not update_fields:
2116
+ return {'success': True, 'message': '没有需要更新的字段'}
2117
+
2118
+ # 执行更新
2119
+ update_sql = f'''
2120
+ UPDATE user_profiles
2121
+ SET {', '.join(update_fields)}
2122
+ WHERE user_id = %s
2123
+ '''
2124
+ update_values.append(user_id)
2125
+
2126
+ cursor.execute(update_sql, update_values)
2127
+
2128
+ if cursor.rowcount > 0:
2129
+ return {'success': True, 'message': '用户资料更新成功'}
2130
+ else:
2131
+ return {'success': False, 'message': '用户资料更新失败'}
2132
+
2133
+ except Exception as e:
2134
+ return {'success': False, 'message': f'用户资料更新失败: {str(e)}'}
2135
+ finally:
2136
+ cursor.close()
2137
+ conn.close()
2138
+
1925
2139
 
1926
2140
  # Flask集成装饰器
1927
2141
  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.120
3
+ Version: 4.0.122
4
4
  Home-page: https://pypi.org/project/mdbq
5
5
  Author: xigua,
6
6
  Author-email: 2587125111@qq.com
@@ -1 +0,0 @@
1
- VERSION = '4.0.120'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes