11"""
2- Helpers specific to deal with data structures from the Wright Group's Bluesky deployment
2+ Helpers and containers for data structures in the Wright Group's Bluesky deployment
33https://github.com/wright-group/bluesky-in-a-box/
44"""
55
88import datetime
99import pathlib
1010import logging
11- from typing import NamedTuple
11+ from typing import NamedTuple , Generator , Iterable
1212
1313from .._open import open as wt5_open
1414
@@ -111,56 +111,76 @@ def folder(self):
111111 )
112112
113113
114- def match_identifier ( dir : pathlib .Path , ** bluesky_identifier ) -> list [ BlueskyFolder ]:
114+ def filter_bluesky ( items : Iterable [ pathlib .Path ] , ** bluesky_identifiers ) -> Generator [ pathlib . Path , None , None ]:
115115 """
116- walk a directory to find bluesky folder names that match the specified identifiers
116+ Filter an iterator of folder names for bluesky folder pattern that match specified values.
117117
118118 Parameters
119119 ----------
120120
121- dir: path-like
122- the directory to iterate through
123-
121+ items: pathlikes
122+ potential paths of bluesky folders
123+
124124 kwargs
125125 ------
126126
127127 bluesky_identifiers
128128 keys corresponding to FolderInfo properties (e.g. date, plan).
129129
130- Returns
130+ Yields
131131 -------
132- matches: list of BlueskyFolder objects
133- BlueskyFolders corresponding to full matches with the bluesky_identifiers
132+
133+ pathlib.Path:
134+ bluesky folders corresponding to full matches with the bluesky_identifiers
135+
136+ Examples
137+ --------
138+ ```
139+ # match within a directory
140+ spooky_folders = [
141+ info for info in filter_bluesky(
142+ data_folder.iterdir(),
143+ date="2025-10-31"
144+ )
145+ ]
146+ ```
134147 """
135- for key in bluesky_identifier .keys ():
148+ for key in bluesky_identifiers .keys ():
136149 assert key in FolderInfo ._fields
137150
138- keep = []
151+ for item in map (pathlib .Path , items ):
152+ if (info := parse_folder_name (item .name )) is not None :
153+ idict = info ._asdict ()
154+ if all (idict [k ] == v for k ,v in bluesky_identifiers .items ()):
155+ yield item
139156
140- for info in map (
141- lambda item : parse_folder_name (item .name ),
142- filter (
143- lambda item : item .is_dir () and re .fullmatch (__folder_seed__ , item .name ), dir .iterdir ()
144- ),
145- ):
146- idict = info ._asdict ()
147- if all (idict [k ] == bluesky_identifier [k ] for k in bluesky_identifier .keys ()):
148- keep .append (BlueskyFolder (dir / info .folder ))
149157
150- return keep
158+ def bluesky_paths (dir : pathlib .Path , ** bluesky_identifiers ) -> list [pathlib .Path ]:
159+ """
160+ walk a directory to find bluesky folder names that match the specified identifiers.
151161
162+ Parameters
163+ ----------
152164
153- def parse_folder_contents (folder : str ) -> FolderInfo | None :
154- """
155- (Coming soon!)
156- Parse key identifiers from a bluesky folder based on the data inside.
165+ dir: path-like
166+ the directory to iterate through
157167
158- See also
159- --------
160- parse_folder_name:
161- Use the folder name, rather than data inside the folder.
168+ kwargs
169+ ------
170+
171+ bluesky_identifiers
172+ keys corresponding to FolderInfo properties (e.g. date, plan).
173+
174+ Returns
175+ -------
176+ matches: list of BlueskyFolder objects
177+ BlueskyFolders corresponding to full matches with the bluesky_identifiers
162178 """
163- raise NotImplementedError
179+
180+ return sorted ([
181+ dir / info .folder
182+ for info in filter_bluesky (dir .iterdir (), ** bluesky_identifiers )
183+ ])
164184
165185
166186def parse_folder_name (folder : str ) -> FolderInfo | None :
@@ -178,14 +198,14 @@ def parse_folder_name(folder: str) -> FolderInfo | None:
178198 if the name is parsed, returns a FolderInfo object.
179199 otherwise, returns None.
180200 """
201+ out = None
181202 if ((uid_match := re .fullmatch (r"(?P<uid>\w{8})" , folder .split ()[- 1 ])) is not None ) and (
182203 (datetime_match := __datetime_seed__ .match (folder )) is not None
183204 ):
184205 matchdict = uid_match .groupdict () | datetime_match .groupdict ()
185206 matchdict ["name" ] = " " .join (folder .split ()[3 :- 1 ])
186- return _to_object (matchdict )
187- else :
188- return None
207+ out = _to_object (matchdict )
208+ return out
189209
190210
191211def _to_object (mdict : dict ) -> FolderInfo :
0 commit comments