organize_project.py 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. 项目结构优化脚本
  5. 用于重新组织项目文件结构,创建更清晰的目录布局
  6. """
  7. import os
  8. import shutil
  9. from pathlib import Path
  10. def create_project_structure():
  11. """创建标准的项目目录结构"""
  12. base_dir = Path.cwd()
  13. # 定义目录结构
  14. directories = [
  15. 'src', # 源代码目录
  16. 'src/core', # 核心模块
  17. 'src/utils', # 工具模块
  18. 'src/config', # 配置模块
  19. 'tests', # 测试目录
  20. 'docs', # 文档目录
  21. 'examples', # 示例代码
  22. 'scripts', # 脚本目录
  23. 'data', # 数据目录
  24. 'data/models', # 模型文件
  25. 'data/samples', # 样本数据
  26. 'output', # 输出目录
  27. 'logs', # 日志目录
  28. ]
  29. # 创建目录
  30. for directory in directories:
  31. dir_path = base_dir / directory
  32. dir_path.mkdir(parents=True, exist_ok=True)
  33. print(f"✓ 创建目录: {directory}")
  34. return base_dir, directories
  35. def move_files_to_structure(base_dir):
  36. """将现有文件移动到新的目录结构中"""
  37. # 文件移动映射
  38. file_moves = {
  39. # 核心模块
  40. 'detector.py': 'src/core/',
  41. 'image_processor.py': 'src/core/',
  42. 'model_inference.py': 'src/core/',
  43. 'post_processor.py': 'src/core/',
  44. 'file_manager.py': 'src/utils/',
  45. 'report_generator.py': 'src/utils/',
  46. # 配置模块
  47. 'config.py': 'src/config/',
  48. # 主入口
  49. 'main.py': 'src/',
  50. # 测试文件
  51. 'test_refactored.py': 'tests/',
  52. # 脚本
  53. 'organize_project.py': 'scripts/',
  54. # 模型文件
  55. 'model/': 'data/models/',
  56. }
  57. # 执行文件移动
  58. for src_path, dst_dir in file_moves.items():
  59. src_full = base_dir / src_path
  60. dst_full = base_dir / dst_dir
  61. if src_full.exists():
  62. if src_full.is_dir():
  63. # 移动目录
  64. dst_path = dst_full / src_full.name
  65. if dst_path.exists():
  66. shutil.rmtree(dst_path)
  67. shutil.move(str(src_full), str(dst_full))
  68. print(f"✓ 移动目录: {src_path} -> {dst_dir}")
  69. else:
  70. # 移动文件
  71. dst_path = dst_full / src_full.name
  72. if dst_path.exists():
  73. dst_path.unlink()
  74. shutil.move(str(src_full), str(dst_full))
  75. print(f"✓ 移动文件: {src_path} -> {dst_dir}")
  76. else:
  77. print(f"⚠ 文件不存在: {src_path}")
  78. def create_init_files(base_dir):
  79. """创建__init__.py文件"""
  80. init_files = [
  81. 'src/__init__.py',
  82. 'src/core/__init__.py',
  83. 'src/utils/__init__.py',
  84. 'src/config/__init__.py',
  85. 'tests/__init__.py',
  86. ]
  87. for init_file in init_files:
  88. init_path = base_dir / init_file
  89. if not init_path.exists():
  90. init_path.write_text('# -*- coding: utf-8 -*-\n')
  91. print(f"✓ 创建: {init_file}")
  92. def update_imports_in_files(base_dir):
  93. """更新文件中的导入路径"""
  94. # 需要更新导入的文件
  95. files_to_update = [
  96. 'src/main.py',
  97. 'src/core/detector.py',
  98. 'tests/test_refactored.py',
  99. ]
  100. # 导入路径映射
  101. import_mapping = {
  102. 'from config import': 'from src.config.config import',
  103. 'from detector import': 'from src.core.detector import',
  104. 'from image_processor import': 'from src.core.image_processor import',
  105. 'from model_inference import': 'from src.core.model_inference import',
  106. 'from post_processor import': 'from src.core.post_processor import',
  107. 'from file_manager import': 'from src.utils.file_manager import',
  108. 'from report_generator import': 'from src.utils.report_generator import',
  109. }
  110. for file_path in files_to_update:
  111. full_path = base_dir / file_path
  112. if full_path.exists():
  113. try:
  114. content = full_path.read_text(encoding='utf-8')
  115. # 更新导入语句
  116. for old_import, new_import in import_mapping.items():
  117. content = content.replace(old_import, new_import)
  118. full_path.write_text(content, encoding='utf-8')
  119. print(f"✓ 更新导入: {file_path}")
  120. except Exception as e:
  121. print(f"⚠ 更新失败 {file_path}: {e}")
  122. def create_setup_files(base_dir):
  123. """创建项目配置文件"""
  124. # 创建setup.py
  125. setup_content = '''#!/usr/bin/env python3
  126. # -*- coding: utf-8 -*-
  127. from setuptools import setup, find_packages
  128. with open("README.md", "r", encoding="utf-8") as fh:
  129. long_description = fh.read()
  130. with open("requirements.txt", "r", encoding="utf-8") as fh:
  131. requirements = [line.strip() for line in fh if line.strip() and not line.startswith("#")]
  132. setup(
  133. name="uav-detector",
  134. version="2.0.0",
  135. author="UAV Detection Team",
  136. description="基于ONNX的无人机检测系统",
  137. long_description=long_description,
  138. long_description_content_type="text/markdown",
  139. packages=find_packages(),
  140. classifiers=[
  141. "Development Status :: 4 - Beta",
  142. "Intended Audience :: Developers",
  143. "License :: OSI Approved :: MIT License",
  144. "Operating System :: OS Independent",
  145. "Programming Language :: Python :: 3",
  146. "Programming Language :: Python :: 3.8",
  147. "Programming Language :: Python :: 3.9",
  148. "Programming Language :: Python :: 3.10",
  149. ],
  150. python_requires=">=3.8",
  151. install_requires=requirements,
  152. entry_points={
  153. "console_scripts": [
  154. "uav-detect=src.main:main",
  155. ],
  156. },
  157. )
  158. '''
  159. setup_path = base_dir / 'setup.py'
  160. setup_path.write_text(setup_content, encoding='utf-8')
  161. print("✓ 创建: setup.py")
  162. # 创建.gitignore
  163. gitignore_content = '''# Python
  164. __pycache__/
  165. *.py[cod]
  166. *$py.class
  167. *.so
  168. .Python
  169. build/
  170. develop-eggs/
  171. dist/
  172. downloads/
  173. eggs/
  174. .eggs/
  175. lib/
  176. lib64/
  177. parts/
  178. sdist/
  179. var/
  180. wheels/
  181. *.egg-info/
  182. .installed.cfg
  183. *.egg
  184. PIPFILE.lock
  185. # Virtual Environment
  186. .venv/
  187. venv/
  188. ENV/
  189. env/
  190. # IDE
  191. .vscode/
  192. .idea/
  193. *.swp
  194. *.swo
  195. *~
  196. # OS
  197. .DS_Store
  198. .DS_Store?
  199. ._*
  200. .Spotlight-V100
  201. .Trashes
  202. ehthumbs.db
  203. Thumbs.db
  204. # Project specific
  205. output/
  206. logs/
  207. *.log
  208. data/samples/*
  209. !data/samples/.gitkeep
  210. '''
  211. gitignore_path = base_dir / '.gitignore'
  212. if not gitignore_path.exists():
  213. gitignore_path.write_text(gitignore_content, encoding='utf-8')
  214. print("✓ 创建: .gitignore")
  215. def create_placeholder_files(base_dir):
  216. """创建占位文件"""
  217. placeholders = [
  218. ('data/samples/.gitkeep', ''),
  219. ('logs/.gitkeep', ''),
  220. ('output/.gitkeep', ''),
  221. ('docs/API.md', '# API 文档\n\n待完善...\n'),
  222. ('examples/basic_usage.py', '#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n"""基本使用示例"""\n\n# 待完善...\n'),
  223. ]
  224. for file_path, content in placeholders:
  225. full_path = base_dir / file_path
  226. if not full_path.exists():
  227. full_path.write_text(content, encoding='utf-8')
  228. print(f"✓ 创建占位文件: {file_path}")
  229. def main():
  230. """主函数"""
  231. print("🚀 开始项目结构重构...")
  232. print("=" * 50)
  233. try:
  234. # 1. 创建目录结构
  235. print("\n📁 创建目录结构...")
  236. base_dir, directories = create_project_structure()
  237. # 2. 移动文件
  238. print("\n📦 移动文件到新结构...")
  239. move_files_to_structure(base_dir)
  240. # 3. 创建__init__.py文件
  241. print("\n📄 创建__init__.py文件...")
  242. create_init_files(base_dir)
  243. # 4. 更新导入路径
  244. print("\n🔄 更新导入路径...")
  245. update_imports_in_files(base_dir)
  246. # 5. 创建配置文件
  247. print("\n⚙️ 创建项目配置文件...")
  248. create_setup_files(base_dir)
  249. # 6. 创建占位文件
  250. print("\n📝 创建占位文件...")
  251. create_placeholder_files(base_dir)
  252. print("\n" + "=" * 50)
  253. print("🎉 项目结构重构完成!")
  254. print("\n新的项目结构:")
  255. print("├── src/ # 源代码")
  256. print("│ ├── core/ # 核心模块")
  257. print("│ ├── utils/ # 工具模块")
  258. print("│ ├── config/ # 配置模块")
  259. print("│ └── main.py # 主入口")
  260. print("├── tests/ # 测试代码")
  261. print("├── docs/ # 文档")
  262. print("├── examples/ # 示例代码")
  263. print("├── scripts/ # 脚本")
  264. print("├── data/ # 数据文件")
  265. print("│ ├── models/ # 模型文件")
  266. print("│ └── samples/ # 样本数据")
  267. print("├── output/ # 输出目录")
  268. print("├── logs/ # 日志目录")
  269. print("├── setup.py # 安装配置")
  270. print("├── requirements.txt # 依赖列表")
  271. print("└── README.md # 项目说明")
  272. except Exception as e:
  273. print(f"❌ 重构过程中出现错误: {e}")
  274. return False
  275. return True
  276. if __name__ == '__main__':
  277. success = main()
  278. if success:
  279. print("\n✅ 可以使用以下命令测试新结构:")
  280. print(" python -m src.main --help")
  281. print(" python -m pytest tests/")
  282. else:
  283. print("\n❌ 重构失败,请检查错误信息")