1
0

cache_manager.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. """Image Cache Manager for pre-generating and managing image previews."""
  2. import os
  3. import json
  4. import asyncio
  5. import logging
  6. from pathlib import Path
  7. from modules.core.pattern_manager import list_theta_rho_files, THETA_RHO_DIR
  8. logger = logging.getLogger(__name__)
  9. # Constants
  10. CACHE_DIR = os.path.join(THETA_RHO_DIR, "cached_images")
  11. def ensure_cache_dir():
  12. """Ensure the cache directory exists with proper permissions."""
  13. try:
  14. Path(CACHE_DIR).mkdir(parents=True, exist_ok=True)
  15. for root, dirs, files in os.walk(CACHE_DIR):
  16. try:
  17. os.chmod(root, 0o777)
  18. for file in files:
  19. file_path = os.path.join(root, file)
  20. try:
  21. os.chmod(file_path, 0o666)
  22. except Exception as e:
  23. logger.error(f"Failed to set permissions for file {file_path}: {str(e)}")
  24. except Exception as e:
  25. logger.error(f"Failed to set permissions for directory {root}: {str(e)}")
  26. continue
  27. except Exception as e:
  28. logger.error(f"Failed to set cache directory permissions: {str(e)}")
  29. pass
  30. def get_cache_path(pattern_file):
  31. """Get the cache path for a pattern file."""
  32. # Create subdirectories in cache to match the pattern file structure
  33. cache_subpath = os.path.dirname(pattern_file)
  34. cache_dir = os.path.join(CACHE_DIR, cache_subpath)
  35. # Ensure the subdirectory exists
  36. os.makedirs(cache_dir, exist_ok=True)
  37. try:
  38. os.chmod(cache_dir, 0o777)
  39. except Exception as e:
  40. logger.error(f"Failed to set permissions for cache subdirectory {cache_dir}: {str(e)}")
  41. # Use just the filename part for the cache file
  42. filename = os.path.basename(pattern_file)
  43. safe_name = filename.replace('\\', '_')
  44. return os.path.join(cache_dir, f"{safe_name}.png")
  45. def needs_cache(pattern_file):
  46. """Check if a pattern file needs its cache generated."""
  47. cache_path = get_cache_path(pattern_file)
  48. return not os.path.exists(cache_path)
  49. async def generate_image_preview(pattern_file):
  50. """Generate image preview for a single pattern file."""
  51. from modules.core.preview import generate_preview_image
  52. try:
  53. image_content = await generate_preview_image(pattern_file)
  54. cache_path = get_cache_path(pattern_file)
  55. with open(cache_path, 'wb') as f:
  56. f.write(image_content)
  57. try:
  58. os.chmod(cache_path, 0o666)
  59. except Exception as e:
  60. logger.error(f"Failed to set cache file permissions for {pattern_file}: {str(e)}")
  61. pass
  62. return True
  63. except Exception as e:
  64. logger.error(f"Failed to generate image for {pattern_file}: {str(e)}")
  65. return False
  66. async def generate_all_image_previews():
  67. """Generate image previews for all pattern files."""
  68. ensure_cache_dir()
  69. pattern_files = [f for f in list_theta_rho_files() if f.endswith('.thr')]
  70. patterns_to_cache = [f for f in pattern_files if needs_cache(f)]
  71. total_files = len(patterns_to_cache)
  72. if total_files == 0:
  73. logger.info("All patterns are already cached")
  74. return
  75. logger.info(f"Generating image cache for {total_files} uncached .thr patterns...")
  76. batch_size = 5
  77. successful = 0
  78. for i in range(0, total_files, batch_size):
  79. batch = patterns_to_cache[i:i + batch_size]
  80. tasks = [generate_image_preview(file) for file in batch]
  81. results = await asyncio.gather(*tasks)
  82. successful += sum(1 for r in results if r)
  83. logger.info(f"Image cache generation completed: {successful}/{total_files} patterns cached")