Skip to content

Commit 4115788

Browse files
committed
Updated directory variable for readability to subdir.
1 parent 0951583 commit 4115788

File tree

1 file changed

+46
-30
lines changed

1 file changed

+46
-30
lines changed

src/models/image_dir.py

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
LOGGER = getLogger(__name__)
3030
SUPPORTED_EXTS = {"jpg", "jpeg", "png", "gif"}
3131

32-
3332
class imageDir(Camera, Reconfigurable):
3433
class Properties(NamedTuple):
3534
supports_pcd: bool = False
@@ -43,11 +42,11 @@ class Properties(NamedTuple):
4342
directory_index: dict
4443
root_dir: str = "/tmp"
4544
ext: str = "jpg"
46-
dir: str
45+
sub_dir: str = ""
4746

4847
# Precomputed once per configured (dir, ext)
49-
sorted_files: List[str]
50-
dir_len: int
48+
sorted_files: List[str] = []
49+
sub_dir_len: int = 0
5150

5251
# Constructor
5352
@classmethod
@@ -99,15 +98,21 @@ def reconfigure(
9998
attrs = config.attributes.fields
10099
self.root_dir = attrs.get("root_dir").string_value if "root_dir" in attrs else "/tmp"
101100
self.ext = (attrs.get("ext").string_value if "ext" in attrs else "jpg").lower()
102-
self.dir = attrs.get("dir").string_value if "dir" in attrs else ""
101+
self.sub_dir = attrs.get("dir").string_value if "dir" in attrs else ""
102+
103+
# Log after attributes are set
104+
LOGGER.info(
105+
"image-dir: reconfigured name=%s root=%s sub_dir=%s ext=%s",
106+
self.name, self.root_dir, self.sub_dir, self.ext
107+
)
103108

104-
requested_dir = os.path.join(self.root_dir, self.dir) if self.dir else self.root_dir
109+
requested_dir = os.path.join(self.root_dir, self.sub_dir) if self.sub_dir else self.root_dir
105110

106111
# Build the fixed, chronologically sorted image list (files in the directory) once
107112
self.sorted_files = self._get_sorted_files(requested_dir, self.ext)
108-
self.dir_len = len(self.sorted_files)
113+
self.sub_dir_len = len(self.sorted_files)
109114

110-
if self.dir_len == 0:
115+
if self.sub_dir_len == 0:
111116
raise ViamError(f"No images with valid timestamp or numeric index found in {requested_dir}")
112117

113118
self.directory_index = {requested_dir: 0}
@@ -120,24 +125,22 @@ async def get_image(
120125
metadata: Optional[Mapping[str, Any]] = None,
121126
**kwargs,
122127
) -> ViamImage:
123-
124128
extra = extra or {}
125-
129+
126130
# This code prevents changing dir/ext on a per-call basis
127131
# Enforces reconfigure() for such changes
128-
if extra.get("dir") and extra["dir"] != self.dir:
132+
if extra.get("dir") and extra["dir"] != self.sub_dir:
129133
raise ViamError("Per-call 'dir' override not supported; reconfigure instead.")
130134
if extra.get("ext") and extra["ext"].lower() != self.ext:
131135
raise ViamError("Per-call 'ext' override not supported; reconfigure instead.")
132136

133-
requested_dir = os.path.join(self.root_dir, self.dir)
137+
requested_dir = os.path.join(self.root_dir, self.sub_dir)
134138
if not os.path.isdir(requested_dir):
135139
raise ViamError("configured directory no longer exists")
136-
if self.dir_len == 0 or not self.sorted_files:
140+
if self.sub_dir_len == 0 or not self.sorted_files:
137141
raise ViamError("No images preloaded. Did reconfigure fail?")
138142

139143
image_index: int
140-
141144

142145
# Direct index setting
143146
if extra.get("index") is not None:
@@ -154,22 +157,37 @@ async def get_image(
154157
# Default: Start at 0
155158
else:
156159
image_index = 0
157-
160+
158161
# Wrap with precomputed length and use precomputed sorted list
159-
n = self.dir_len
162+
n = self.sub_dir_len
160163
image_index = int(image_index) % n
161-
164+
162165
file_path = os.path.join(requested_dir, self.sorted_files[image_index])
163166
if not os.path.isfile(file_path):
164167
raise ViamError(f"Image file not found: {file_path}")
165-
166-
# Open safely and convert to ViamImage
168+
169+
# Resolve mime type
170+
if isinstance(mime_type, CameraMimeType):
171+
mt = mime_type
172+
else:
173+
mt_str = mime_type.strip().lower() if mime_type is not None else ""
174+
# treat these as "no preference" and pick by ext
175+
if mt_str in {"", "-"}:
176+
mt_str = "image/png" if self.ext.lower() == "png" else "image/jpeg"
177+
if mt_str == "image/jpg":
178+
mt_str = "image/jpeg"
179+
try:
180+
mt = CameraMimeType.from_string(mt_str)
181+
except Exception:
182+
LOGGER.warning("Unsupported mime '%s'; defaulting to image/jpeg", mt_str)
183+
mt = CameraMimeType.JPEG
184+
167185
with Image.open(file_path) as img:
168-
vi_img = pil_to_viam_image(img.convert("RGB"), CameraMimeType.from_string(mime_type))
169-
186+
vi_img = pil_to_viam_image(img.convert("RGB"), mt)
187+
170188
# Increment safely with modulo
171189
self.directory_index[requested_dir] = (image_index + 1) % n
172-
190+
173191
return vi_img
174192

175193

@@ -237,18 +255,17 @@ def _get_sorted_files(self, dir, ext):
237255
idx.append((f, key))
238256
# else: unknown for now; we may warn after choosing mode
239257

240-
# Choose majority; tie → timestamp
258+
# Sort by majority if mixed filenames: tie → timestamp
241259
if len(ts) >= len(idx) and len(ts) > 0:
242-
LOGGER.info(f"Sorting mode: timestamp ({len(ts)} files)")
243260
keep = {f for f, _ in ts}
244261
for f in files:
245262
if f not in keep:
246263
LOGGER.warning(f"Skipping file without parsable timestamp: {f}")
247264
ts.sort(key=lambda x: (x[1], x[0])) # stable & deterministic
248265
return [f for f, _ in ts]
249266

267+
# Sort by numeric index
250268
if len(idx) > 0:
251-
LOGGER.info(f"Sorting mode: index ({len(idx)} files)")
252269
keep = {f for f, _ in idx}
253270
for f in files:
254271
if f not in keep:
@@ -261,9 +278,8 @@ def _get_sorted_files(self, dir, ext):
261278
LOGGER.warning(f"Skipping file without timestamp or numeric index: {f}")
262279
return []
263280

264-
265281
def _jog_index(self, index_jog, requested_dir):
266-
n = self.dir_len if self.dir_len > 0 else 1
282+
n = self.sub_dir_len if self.sub_dir_len > 0 else 1
267283
current_index = self.directory_index.get(requested_dir, 0) % n
268284

269285
return (current_index + int(index_jog)) % n
@@ -281,7 +297,7 @@ async def get_images(
281297
extra = {}
282298

283299
# Determine source name
284-
source_name = self.dir or ""
300+
source_name = self.sub_dir or ""
285301

286302
# Apply filtering if specified
287303
if filter_source_names is not None and len(filter_source_names) > 0 and source_name not in filter_source_names:
@@ -312,10 +328,10 @@ async def do_command(
312328
if setDict.get("dir") is not None or setDict.get("ext") is not None:
313329
raise ViamError("Changing 'dir' or 'ext' requires a reconfigure.")
314330

315-
requested_dir = os.path.join(self.root_dir, self.dir)
331+
requested_dir = os.path.join(self.root_dir, self.sub_dir)
316332

317333
if setDict.get("index") is not None:
318-
n = max(1, self.dir_len)
334+
n = max(1, self.sub_dir_len)
319335
self.directory_index[requested_dir] = setDict["index"] % n
320336
ret = {"index": self.directory_index[requested_dir]}
321337

0 commit comments

Comments
 (0)