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.
- {mdbq-4.0.120 → mdbq-4.0.122}/PKG-INFO +2 -2
- mdbq-4.0.122/mdbq/__version__.py +1 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/auth/auth_backend.py +215 -1
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq.egg-info/PKG-INFO +2 -2
- mdbq-4.0.120/mdbq/__version__.py +0 -1
- {mdbq-4.0.120 → mdbq-4.0.122}/README.txt +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/__init__.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/auth/__init__.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/auth/rate_limiter.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/js/__init__.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/js/jc.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/log/__init__.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/log/mylogger.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/myconf/__init__.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/myconf/myconf.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/mysql/__init__.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/mysql/deduplicator.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/mysql/mysql.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/mysql/s_query.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/mysql/unique_.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/mysql/uploader.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/other/__init__.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/other/download_sku_picture.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/other/error_handler.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/other/otk.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/other/pov_city.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/other/ua_sj.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/pbix/__init__.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/pbix/pbix_refresh.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/pbix/refresh_all.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/redis/__init__.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/redis/getredis.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/redis/redis_cache.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/route/__init__.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/route/analytics.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/route/monitor.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/route/routes.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/selenium/__init__.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/selenium/get_driver.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq/spider/__init__.py +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq.egg-info/SOURCES.txt +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq.egg-info/dependency_links.txt +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/mdbq.egg-info/top_level.txt +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/setup.cfg +0 -0
- {mdbq-4.0.120 → mdbq-4.0.122}/setup.py +0 -0
|
@@ -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
|
-
|
|
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):
|
mdbq-4.0.120/mdbq/__version__.py
DELETED
|
@@ -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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|