mdbq 4.0.103__tar.gz → 4.0.105__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 (44) hide show
  1. {mdbq-4.0.103 → mdbq-4.0.105}/PKG-INFO +1 -1
  2. mdbq-4.0.105/mdbq/__version__.py +1 -0
  3. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/auth/auth_backend.py +51 -63
  4. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq.egg-info/PKG-INFO +1 -1
  5. mdbq-4.0.103/mdbq/__version__.py +0 -1
  6. {mdbq-4.0.103 → mdbq-4.0.105}/README.txt +0 -0
  7. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/__init__.py +0 -0
  8. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/auth/__init__.py +0 -0
  9. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/auth/rate_limiter.py +0 -0
  10. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/js/__init__.py +0 -0
  11. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/js/jc.py +0 -0
  12. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/log/__init__.py +0 -0
  13. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/log/mylogger.py +0 -0
  14. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/myconf/__init__.py +0 -0
  15. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/myconf/myconf.py +0 -0
  16. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/mysql/__init__.py +0 -0
  17. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/mysql/deduplicator.py +0 -0
  18. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/mysql/mysql.py +0 -0
  19. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/mysql/s_query.py +0 -0
  20. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/mysql/unique_.py +0 -0
  21. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/mysql/uploader.py +0 -0
  22. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/other/__init__.py +0 -0
  23. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/other/download_sku_picture.py +0 -0
  24. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/other/error_handler.py +0 -0
  25. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/other/otk.py +0 -0
  26. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/other/pov_city.py +0 -0
  27. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/other/ua_sj.py +0 -0
  28. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/pbix/__init__.py +0 -0
  29. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/pbix/pbix_refresh.py +0 -0
  30. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/pbix/refresh_all.py +0 -0
  31. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/redis/__init__.py +0 -0
  32. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/redis/getredis.py +0 -0
  33. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/route/__init__.py +0 -0
  34. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/route/analytics.py +0 -0
  35. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/route/monitor.py +0 -0
  36. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/route/routes.py +0 -0
  37. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/selenium/__init__.py +0 -0
  38. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/selenium/get_driver.py +0 -0
  39. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq/spider/__init__.py +0 -0
  40. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq.egg-info/SOURCES.txt +0 -0
  41. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq.egg-info/dependency_links.txt +0 -0
  42. {mdbq-4.0.103 → mdbq-4.0.105}/mdbq.egg-info/top_level.txt +0 -0
  43. {mdbq-4.0.103 → mdbq-4.0.105}/setup.cfg +0 -0
  44. {mdbq-4.0.103 → mdbq-4.0.105}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mdbq
3
- Version: 4.0.103
3
+ Version: 4.0.105
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.105'
@@ -147,8 +147,8 @@ class StandaloneAuthManager:
147
147
  ping=1,
148
148
  charset='utf8mb4',
149
149
  cursorclass=pymysql.cursors.DictCursor,
150
- autocommit=True, # 启用自动提交,避免锁冲突
151
- init_command="SET time_zone = '+00:00'"
150
+ autocommit=True # 启用自动提交,避免锁冲突
151
+ # 使用系统本地时区,不强制设置UTC
152
152
  )
153
153
 
154
154
  except Exception as e:
@@ -515,15 +515,9 @@ class StandaloneAuthManager:
515
515
  }
516
516
 
517
517
  # 检查账户锁定状态
518
- current_time_utc = datetime.now(timezone.utc)
519
- if locked_until:
520
- if locked_until.tzinfo is None:
521
- locked_until = locked_until.replace(tzinfo=timezone.utc)
522
- elif locked_until.tzinfo != timezone.utc:
523
- locked_until = locked_until.astimezone(timezone.utc)
524
-
525
- if locked_until > current_time_utc:
526
- remaining_seconds = int((locked_until - current_time_utc).total_seconds())
518
+ current_time = datetime.now()
519
+ if locked_until and locked_until > current_time:
520
+ remaining_seconds = int((locked_until - current_time).total_seconds())
527
521
  self._log_login_attempt(username_or_email, ip_address, user_agent, 'failure', 'account_locked', user_id)
528
522
  self._record_ip_failure(ip_address, 'login')
529
523
  return {
@@ -540,7 +534,7 @@ class StandaloneAuthManager:
540
534
 
541
535
  if login_attempts >= self.auth_config['max_login_attempts']:
542
536
  lockout_duration = self.auth_config['lockout_duration']
543
- locked_until = current_time_utc + timedelta(seconds=lockout_duration)
537
+ locked_until = current_time + timedelta(seconds=lockout_duration)
544
538
  cursor.execute('''
545
539
  UPDATE users SET login_attempts = %s, locked_until = %s WHERE id = %s
546
540
  ''', (login_attempts, locked_until, user_id))
@@ -573,7 +567,7 @@ class StandaloneAuthManager:
573
567
  # 登录成功,重置尝试次数
574
568
  cursor.execute('''
575
569
  UPDATE users SET login_attempts = 0, locked_until = NULL, last_login = %s WHERE id = %s
576
- ''', (current_time_utc, user_id))
570
+ ''', (current_time, user_id))
577
571
 
578
572
  # 记录成功登录
579
573
  self._log_login_attempt(username_or_email, ip_address, user_agent, 'success', None, user_id)
@@ -586,7 +580,7 @@ class StandaloneAuthManager:
586
580
  'email': email,
587
581
  'role': role,
588
582
  'permissions': self._safe_json_parse(permissions),
589
- 'last_login': current_time_utc.isoformat()
583
+ 'last_login': current_time.isoformat()
590
584
  }
591
585
 
592
586
  finally:
@@ -595,16 +589,16 @@ class StandaloneAuthManager:
595
589
 
596
590
  def generate_access_token(self, user_info):
597
591
  """生成访问令牌"""
598
- now_utc = datetime.now(timezone.utc)
599
- exp_utc = now_utc + timedelta(seconds=self.auth_config['access_token_expires'])
592
+ now = datetime.now()
593
+ exp = now + timedelta(seconds=self.auth_config['access_token_expires'])
600
594
 
601
595
  payload = {
602
596
  'user_id': user_info['user_id'],
603
597
  'username': user_info['username'],
604
598
  'role': user_info['role'],
605
599
  'permissions': user_info['permissions'],
606
- 'iat': int(now_utc.timestamp()),
607
- 'exp': int(exp_utc.timestamp()),
600
+ 'iat': int(now.timestamp()),
601
+ 'exp': int(exp.timestamp()),
608
602
  'type': 'access'
609
603
  }
610
604
 
@@ -646,7 +640,7 @@ class StandaloneAuthManager:
646
640
  cursor = conn.cursor()
647
641
 
648
642
  try:
649
- current_time_utc = datetime.now(timezone.utc)
643
+ current_time = datetime.now()
650
644
 
651
645
  # 软删除:将该用户在该域名下的相同设备指纹的所有活跃会话标记为非活跃
652
646
  cursor.execute('''
@@ -702,7 +696,7 @@ class StandaloneAuthManager:
702
696
  full_device_info.get('timezone_offset'),
703
697
  full_device_info.get('language'),
704
698
  full_device_info.get('hardware_concurrency'),
705
- ip_address, ip_address, user_agent, current_time_utc))
699
+ ip_address, ip_address, user_agent, current_time))
706
700
 
707
701
  device_session_id = cursor.lastrowid
708
702
 
@@ -716,9 +710,9 @@ class StandaloneAuthManager:
716
710
  """生成刷新令牌"""
717
711
  token = secrets.token_urlsafe(64)
718
712
  token_hash = hashlib.sha256(token.encode()).hexdigest()
719
- current_time_utc = datetime.now(timezone.utc)
720
- expires_at = current_time_utc + timedelta(seconds=self.auth_config['refresh_token_expires'])
721
- absolute_expires_at = current_time_utc + timedelta(days=self.auth_config['absolute_refresh_expires_days'])
713
+ current_time = datetime.now()
714
+ expires_at = current_time + timedelta(seconds=self.auth_config['refresh_token_expires'])
715
+ absolute_expires_at = current_time + timedelta(days=self.auth_config['absolute_refresh_expires_days'])
722
716
 
723
717
  conn = self.pool.connection()
724
718
  cursor = conn.cursor()
@@ -737,7 +731,7 @@ class StandaloneAuthManager:
737
731
  rotation_count, max_rotations, created_at
738
732
  ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
739
733
  ''', (token_hash, token, user_info['user_id'], device_session_id, expires_at,
740
- absolute_expires_at, 0, self.auth_config['max_refresh_rotations'], current_time_utc))
734
+ absolute_expires_at, 0, self.auth_config['max_refresh_rotations'], current_time))
741
735
 
742
736
  return token
743
737
 
@@ -758,8 +752,7 @@ class StandaloneAuthManager:
758
752
 
759
753
  try:
760
754
  # 验证刷新令牌
761
- current_time_utc = datetime.now(timezone.utc)
762
- current_time_naive = current_time_utc.replace(tzinfo=None)
755
+ current_time = datetime.now()
763
756
 
764
757
  cursor.execute('''
765
758
  SELECT rt.user_id, rt.device_session_id, rt.expires_at, rt.absolute_expires_at,
@@ -775,7 +768,7 @@ class StandaloneAuthManager:
775
768
  AND rt.rotation_count < rt.max_rotations
776
769
  AND rt.is_revoked = 0
777
770
  AND ds.is_active = 1
778
- ''', (token_hash, current_time_naive, current_time_naive))
771
+ ''', (token_hash, current_time, current_time))
779
772
 
780
773
  result = cursor.fetchone()
781
774
 
@@ -787,7 +780,7 @@ class StandaloneAuthManager:
787
780
  UPDATE device_sessions
788
781
  SET last_activity = %s
789
782
  WHERE id = %s
790
- ''', (current_time_utc, result['device_session_id']))
783
+ ''', (current_time, result['device_session_id']))
791
784
 
792
785
  # 生成新的tokens
793
786
  user_info = {
@@ -803,7 +796,7 @@ class StandaloneAuthManager:
803
796
  # 生成新的refresh token(轮换)
804
797
  new_token = secrets.token_urlsafe(64)
805
798
  new_token_hash = hashlib.sha256(new_token.encode()).hexdigest()
806
- token_expires_at = current_time_utc + timedelta(seconds=self.auth_config['refresh_token_expires'])
799
+ token_expires_at = current_time + timedelta(seconds=self.auth_config['refresh_token_expires'])
807
800
 
808
801
  # 删除旧token并插入新token
809
802
  cursor.execute('''
@@ -818,7 +811,7 @@ class StandaloneAuthManager:
818
811
  ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
819
812
  ''', (new_token_hash, new_token, result['user_id'], result['device_session_id'],
820
813
  token_expires_at, result['absolute_expires_at'],
821
- result['rotation_count'] + 1, result['max_rotations'], current_time_utc))
814
+ result['rotation_count'] + 1, result['max_rotations'], current_time))
822
815
 
823
816
  return {
824
817
  'access_token': access_token,
@@ -850,7 +843,7 @@ class StandaloneAuthManager:
850
843
  cursor = conn.cursor()
851
844
 
852
845
  try:
853
- current_time_utc = datetime.now(timezone.utc)
846
+ current_time = datetime.now()
854
847
 
855
848
  # 先查询要登出的设备数量
856
849
  cursor.execute('''
@@ -865,7 +858,7 @@ class StandaloneAuthManager:
865
858
  UPDATE refresh_tokens
866
859
  SET is_revoked = 1, revoked_at = %s, revoked_reason = 'logout'
867
860
  WHERE user_id = %s AND is_revoked = 0
868
- ''', (current_time_utc, user_id))
861
+ ''', (current_time, user_id))
869
862
 
870
863
  # 停用用户的所有设备会话
871
864
  cursor.execute('''
@@ -920,7 +913,7 @@ class StandaloneAuthManager:
920
913
  new_salt = secrets.token_hex(32)
921
914
  new_password_hash = self._hash_password(new_password, new_salt)
922
915
 
923
- current_time_utc = datetime.now(timezone.utc)
916
+ current_time = datetime.now()
924
917
 
925
918
  # 更新密码
926
919
  cursor.execute('''
@@ -935,7 +928,7 @@ class StandaloneAuthManager:
935
928
  UPDATE refresh_tokens
936
929
  SET is_revoked = 1, revoked_at = %s, revoked_reason = 'password_changed'
937
930
  WHERE user_id = %s AND is_revoked = 0
938
- ''', (current_time_utc, user_id))
931
+ ''', (current_time, user_id))
939
932
 
940
933
  # 停用所有设备会话
941
934
  cursor.execute('''
@@ -1013,7 +1006,7 @@ class StandaloneAuthManager:
1013
1006
 
1014
1007
  # 生成重置令牌
1015
1008
  reset_token = secrets.token_urlsafe(32)
1016
- expires_at = datetime.now(timezone.utc) + timedelta(hours=1) # 1小时有效期
1009
+ expires_at = datetime.now() + timedelta(hours=1) # 1小时有效期
1017
1010
 
1018
1011
  # 保存重置令牌
1019
1012
  cursor.execute('''
@@ -1056,7 +1049,7 @@ class StandaloneAuthManager:
1056
1049
  if len(new_password) < 6:
1057
1050
  return {'success': False, 'message': '新密码至少需要6个字符'}
1058
1051
 
1059
- current_time_utc = datetime.now(timezone.utc)
1052
+ current_time = datetime.now()
1060
1053
 
1061
1054
  # 查找有效的重置令牌
1062
1055
  cursor.execute('''
@@ -1065,7 +1058,7 @@ class StandaloneAuthManager:
1065
1058
  WHERE password_reset_token = %s
1066
1059
  AND password_reset_expires > %s
1067
1060
  AND is_active = 1
1068
- ''', (reset_token, current_time_utc))
1061
+ ''', (reset_token, current_time))
1069
1062
 
1070
1063
  user = cursor.fetchone()
1071
1064
  if not user:
@@ -1089,7 +1082,7 @@ class StandaloneAuthManager:
1089
1082
  UPDATE refresh_tokens
1090
1083
  SET is_revoked = 1, revoked_at = %s, revoked_reason = 'password_reset'
1091
1084
  WHERE user_id = %s AND is_revoked = 0
1092
- ''', (current_time_utc, user['id']))
1085
+ ''', (current_time, user['id']))
1093
1086
 
1094
1087
  # 停用所有设备会话
1095
1088
  cursor.execute('''
@@ -1134,16 +1127,10 @@ class StandaloneAuthManager:
1134
1127
 
1135
1128
  locked_until = record['locked_until']
1136
1129
 
1137
- current_time_utc = datetime.now(timezone.utc)
1138
- if locked_until:
1139
- if locked_until.tzinfo is None:
1140
- locked_until = locked_until.replace(tzinfo=timezone.utc)
1141
- elif locked_until.tzinfo != timezone.utc:
1142
- locked_until = locked_until.astimezone(timezone.utc)
1143
-
1144
- if locked_until > current_time_utc:
1145
- remaining_seconds = int((locked_until - current_time_utc).total_seconds())
1146
- return {
1130
+ current_time = datetime.now()
1131
+ if locked_until and locked_until > current_time:
1132
+ remaining_seconds = int((locked_until - current_time).total_seconds())
1133
+ return {
1147
1134
  'blocked': True,
1148
1135
  'remaining_time': remaining_seconds,
1149
1136
  'reason': f'IP被锁定,剩余时间: {remaining_seconds}秒'
@@ -1164,7 +1151,7 @@ class StandaloneAuthManager:
1164
1151
  cursor = conn.cursor()
1165
1152
 
1166
1153
  try:
1167
- now = datetime.now(timezone.utc)
1154
+ now = datetime.now()
1168
1155
 
1169
1156
  cursor.execute('''
1170
1157
  SELECT failure_count, first_failure, lockout_count
@@ -1180,7 +1167,7 @@ class StandaloneAuthManager:
1180
1167
  window_start = now - timedelta(minutes=window_minutes)
1181
1168
  first_failure = record['first_failure']
1182
1169
 
1183
- if first_failure and first_failure.replace(tzinfo=timezone.utc) <= window_start:
1170
+ if first_failure and first_failure <= window_start:
1184
1171
  # 重置计数器
1185
1172
  cursor.execute('''
1186
1173
  UPDATE ip_rate_limits
@@ -1226,14 +1213,14 @@ class StandaloneAuthManager:
1226
1213
 
1227
1214
  def _revoke_device_session(self, cursor, device_session_id, reason='manual'):
1228
1215
  """撤销设备会话"""
1229
- current_time_utc = datetime.now(timezone.utc)
1216
+ current_time = datetime.now()
1230
1217
 
1231
1218
  # 撤销设备相关的refresh token
1232
1219
  cursor.execute('''
1233
1220
  UPDATE refresh_tokens
1234
1221
  SET is_revoked = 1, revoked_at = %s, revoked_reason = %s
1235
1222
  WHERE device_session_id = %s AND is_revoked = 0
1236
- ''', (current_time_utc, reason, device_session_id))
1223
+ ''', (current_time, reason, device_session_id))
1237
1224
 
1238
1225
  # 停用设备会话
1239
1226
  cursor.execute('''
@@ -1429,6 +1416,7 @@ class StandaloneAuthManager:
1429
1416
 
1430
1417
  def logout_device(self, user_id, device_id=None, ip_address=None, user_agent=None, device_info=None, login_domain=''):
1431
1418
  """
1419
+ 【已废弃】
1432
1420
  登出设备(支持两种识别方式)
1433
1421
 
1434
1422
  Args:
@@ -1446,7 +1434,7 @@ class StandaloneAuthManager:
1446
1434
  cursor = conn.cursor()
1447
1435
 
1448
1436
  try:
1449
- current_time_utc = datetime.now(timezone.utc)
1437
+ current_time = datetime.now()
1450
1438
 
1451
1439
  if device_id:
1452
1440
  # 方式1:通过device_id查找设备(用于设备管理界面)
@@ -1504,7 +1492,7 @@ class StandaloneAuthManager:
1504
1492
  UPDATE refresh_tokens
1505
1493
  SET is_revoked = 1, revoked_at = %s, revoked_reason = %s
1506
1494
  WHERE device_session_id = %s AND is_revoked = 0
1507
- ''', (current_time_utc, logout_reason, device_session_id))
1495
+ ''', (current_time, logout_reason, device_session_id))
1508
1496
 
1509
1497
  # 停用设备会话
1510
1498
  cursor.execute('''
@@ -1537,7 +1525,7 @@ class StandaloneAuthManager:
1537
1525
  cursor = conn.cursor()
1538
1526
 
1539
1527
  try:
1540
- current_time_utc = datetime.now(timezone.utc)
1528
+ current_time = datetime.now()
1541
1529
 
1542
1530
  if access_token:
1543
1531
  # 方式1:通过access_token解析出设备会话信息
@@ -1586,7 +1574,7 @@ class StandaloneAuthManager:
1586
1574
  UPDATE refresh_tokens
1587
1575
  SET is_revoked = 1, revoked_at = %s, revoked_reason = 'current_device_logout'
1588
1576
  WHERE device_session_id = %s AND is_revoked = 0
1589
- ''', (current_time_utc, device_session_id))
1577
+ ''', (current_time, device_session_id))
1590
1578
 
1591
1579
  # 停用设备会话
1592
1580
  cursor.execute('''
@@ -1618,7 +1606,7 @@ class StandaloneAuthManager:
1618
1606
  cursor = conn.cursor()
1619
1607
 
1620
1608
  try:
1621
- current_time_utc = datetime.now(timezone.utc)
1609
+ current_time = datetime.now()
1622
1610
 
1623
1611
  # 通过device_id查找设备,确保属于该用户
1624
1612
  cursor.execute('''
@@ -1639,7 +1627,7 @@ class StandaloneAuthManager:
1639
1627
  UPDATE refresh_tokens
1640
1628
  SET is_revoked = 1, revoked_at = %s, revoked_reason = 'specific_device_logout'
1641
1629
  WHERE device_session_id = %s AND is_revoked = 0
1642
- ''', (current_time_utc, device_session_id))
1630
+ ''', (current_time, device_session_id))
1643
1631
 
1644
1632
  # 停用设备会话
1645
1633
  cursor.execute('''
@@ -1735,8 +1723,8 @@ class StandaloneAuthManager:
1735
1723
  cursor = conn.cursor()
1736
1724
 
1737
1725
  try:
1738
- current_time_utc = datetime.now(timezone.utc)
1739
- threshold_time = current_time_utc - timedelta(days=days_threshold)
1726
+ current_time = datetime.now()
1727
+ threshold_time = current_time - timedelta(days=days_threshold)
1740
1728
 
1741
1729
  # 查找不活跃的设备
1742
1730
  cursor.execute('''
@@ -1757,7 +1745,7 @@ class StandaloneAuthManager:
1757
1745
  WHERE device_session_id IN ({})
1758
1746
  AND is_revoked = 0
1759
1747
  '''.format(','.join(['%s'] * len(device_session_ids))),
1760
- [current_time_utc] + device_session_ids)
1748
+ [current_time] + device_session_ids)
1761
1749
 
1762
1750
  # 停用设备会话
1763
1751
  cursor.execute('''
@@ -1891,8 +1879,8 @@ class StandaloneAuthManager:
1891
1879
  cursor = conn.cursor()
1892
1880
 
1893
1881
  try:
1894
- current_time_utc = datetime.now(timezone.utc)
1895
- threshold_time = current_time_utc - timedelta(days=days_threshold)
1882
+ current_time = datetime.now()
1883
+ threshold_time = current_time - timedelta(days=days_threshold)
1896
1884
 
1897
1885
  if user_id:
1898
1886
  # 清理特定用户的旧记录
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mdbq
3
- Version: 4.0.103
3
+ Version: 4.0.105
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.103'
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