Session.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import pickle
  2. from warnings import warn
  3. import os
  4. from tqdm import tqdm
  5. from py.FileUtils import list_folders, list_jpegs_recursive, verify_expected_subfolders
  6. from py.ImageUtils import get_image_date
  7. class Session:
  8. def __init__(self, folder: str):
  9. self.folder = folder
  10. # session name = folder name[33:], the first 33 characters are always the same
  11. self.name = os.path.basename(folder)[33:]
  12. print(f"Session '{self.name}' at folder: {self.folder}")
  13. assert self.name != ""
  14. verify_expected_subfolders(self.folder)
  15. self.scanned = False
  16. # maps lapse files to their exif dates (for statistic and prediction purposes)
  17. self.lapse_dates = {}
  18. # maps motion files to their exif dates (for statistic purposes)
  19. self.motion_dates = {}
  20. # maps exif dates to lapse files (for prediction purposes)
  21. self.lapse_map = {}
  22. self.load_scans()
  23. if not self.scanned:
  24. print("Session not scanned. Run session.scan() to create scan files")
  25. def load_scans(self):
  26. lapse_dates_file = os.path.join("session_scans", self.name, "lapse_dates.pickle")
  27. motion_dates_file = os.path.join("session_scans", self.name, "motion_dates.pickle")
  28. lapse_map_file = os.path.join("session_scans", self.name, "lapse_map.pickle")
  29. lapse_dates_exists = os.path.isfile(lapse_dates_file)
  30. motion_dates_exists = os.path.isfile(motion_dates_file)
  31. lapse_map_exists = os.path.isfile(lapse_map_file)
  32. if lapse_dates_exists and motion_dates_exists and lapse_map_exists:
  33. with open(lapse_dates_file, "rb") as handle:
  34. self.lapse_dates = pickle.load(handle)
  35. with open(motion_dates_file, "rb") as handle:
  36. self.motion_dates_file = pickle.load(handle)
  37. with open(lapse_map_file, "rb") as handle:
  38. self.lapse_map_file = pickle.load(handle)
  39. self.scanned = True
  40. print("Loaded scans.")
  41. else:
  42. if not (not lapse_dates_exists and not motion_dates_exists and not lapse_map_exists):
  43. warn(f"Warning: Only partial scan data available. Not loading.")
  44. self.scanned = False
  45. def save_scans(self):
  46. lapse_dates_file = os.path.join("session_scans", self.name, "lapse_dates.pickle")
  47. motion_dates_file = os.path.join("session_scans", self.name, "motion_dates.pickle")
  48. lapse_map_file = os.path.join("session_scans", self.name, "lapse_map.pickle")
  49. with open(lapse_dates_file, "wb") as handle:
  50. pickle.dump(self.lapse_dates, handle, protocol=pickle.HIGHEST_PROTOCOL)
  51. print(f"Saved {lapse_dates_file}")
  52. with open(motion_dates_file, "wb") as handle:
  53. pickle.dump(self.motion_dates, handle, protocol=pickle.HIGHEST_PROTOCOL)
  54. print(f"Saved {motion_dates_file}")
  55. with open(lapse_map_file, "wb") as handle:
  56. pickle.dump(self.lapse_map, handle, protocol=pickle.HIGHEST_PROTOCOL)
  57. print(f"Saved {lapse_map_file}")
  58. def scan(self, force=False, auto_save=True):
  59. if self.scanned and not force:
  60. raise ValueError("Session is already scanned. Use force=True to scan anyway and override scan progress.")
  61. # Scan motion dates
  62. print("Scanning motion dates...")
  63. self.motion_dates = {}
  64. for motionFile in tqdm(list_jpegs_recursive(os.path.join(self.folder, "Motion"))):
  65. self.motion_dates[os.path.basename(motionFile)] = get_image_date(motionFile)
  66. # Scan lapse dates
  67. print("Scanning lapse dates...")
  68. self.lapse_dates = {}
  69. for motionFile in tqdm(list_jpegs_recursive(os.path.join(self.folder, "Motion"))):
  70. self.motion_dates[os.path.basename(motionFile)] = get_image_date(motionFile)
  71. # Create lapse map
  72. print("Creating lapse map...")
  73. self.lapse_map = {}
  74. for file, date in self.lapse_dates.items():
  75. if date in self.lapse_map:
  76. self.lapse_map[date].append(file)
  77. else:
  78. self.lapse_map[date] = [file]
  79. # Auto save
  80. if auto_save:
  81. print("Saving...")
  82. self.save_scans()