utils.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. from functools import wraps
  2. from flask import session, request, jsonify, redirect, url_for
  3. import socket
  4. import os
  5. import yaml
  6. import subprocess
  7. import platform
  8. from utils.logger_config import logger
  9. # 配置上传文件夹
  10. UPLOAD_FOLDER = 'uploads'
  11. ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp'}
  12. # 登录验证装饰器
  13. def login_required(f):
  14. @wraps(f)
  15. def decorated_function(*args, **kwargs):
  16. if 'logged_in' not in session:
  17. # 如果是 API 请求,返回 401
  18. if request.path.startswith('/api/'):
  19. return jsonify({'success': False, 'message': '未登录'}), 401
  20. # 如果是页面请求,跳转到登录页
  21. # 假设 auth blueprint 注册为 'auth',登录路由名为 'login'
  22. return redirect(url_for('auth.login'))
  23. return f(*args, **kwargs)
  24. return decorated_function
  25. def allowed_file(filename):
  26. """检查文件扩展名是否允许"""
  27. return '.' in filename and \
  28. filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
  29. def get_server_ip():
  30. """获取服务器的本地IP地址"""
  31. try:
  32. # 连接到一个远程地址(不会实际发送数据)
  33. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  34. s.connect(("8.8.8.8", 80))
  35. ip = s.getsockname()[0]
  36. s.close()
  37. return ip
  38. except Exception:
  39. # 如果获取失败,尝试其他方法
  40. try:
  41. hostname = socket.gethostname()
  42. ip = socket.gethostbyname(hostname)
  43. return ip
  44. except Exception:
  45. return "127.0.0.1" # 回退到localhost
  46. def load_led_config():
  47. """读取LED配置文件"""
  48. try:
  49. config_path = 'led_config.yaml'
  50. if os.path.exists(config_path):
  51. with open(config_path, 'r', encoding='utf-8') as f:
  52. config = yaml.safe_load(f)
  53. return config.get('segments', [])
  54. return []
  55. except Exception as e:
  56. logger.error(f"读取LED配置文件失败: {e}")
  57. return []
  58. def ping_ip(ip):
  59. """
  60. Ping IP地址,返回是否通畅
  61. """
  62. if not ip:
  63. return False
  64. system_type = platform.system().lower()
  65. if system_type == 'windows':
  66. # -n 1: 发送1个包
  67. # -w 1000: 超时1000ms
  68. command = ['ping', '-n', '1', '-w', '1000', ip]
  69. else:
  70. # -c 1: 发送1个包
  71. # -W 1: 超时1s
  72. command = ['ping', '-c', '1', '-W', '1', ip]
  73. try:
  74. # 这里的 stdout/stderr=subprocess.DEVNULL 防止输出干扰日志
  75. return subprocess.call(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0
  76. except Exception as e:
  77. logger.error(f"Ping IP {ip} 异常: {e}")
  78. return False