|
1 | 1 | import os |
2 | 2 | from collections.abc import Callable |
3 | 3 | from functools import partial |
| 4 | +import sys |
4 | 5 | from typing import TYPE_CHECKING, TypeVar |
5 | 6 |
|
6 | 7 | import error_messages |
7 | 8 | from AutoSplitImage import RESET_KEYWORD, START_KEYWORD, AutoSplitImage, ImageType |
8 | 9 | from utils import is_valid_image |
| 10 | +from stat import FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_SYSTEM, UF_HIDDEN |
9 | 11 |
|
10 | 12 | if TYPE_CHECKING: |
11 | 13 | from AutoSplit import AutoSplit |
| 14 | + from _typeshed import StrPath |
12 | 15 |
|
13 | 16 | ( |
14 | 17 | DUMMY_FLAG, |
@@ -193,13 +196,39 @@ def validate_before_parsing(autosplit: "AutoSplit", *, show_error: bool = True): |
193 | 196 | return not error |
194 | 197 |
|
195 | 198 |
|
196 | | -def parse_and_validate_images(autosplit: "AutoSplit"): |
197 | | - # Get split images |
198 | | - all_images = [ |
199 | | - AutoSplitImage(os.path.join(autosplit.settings_dict["split_image_directory"], image_name)) |
200 | | - for image_name in os.listdir(autosplit.settings_dict["split_image_directory"]) |
201 | | - ] |
| 199 | +def is_user_file(path: StrPath): |
| 200 | + """Returns False for hidden files, system files and folders.""" |
| 201 | + if os.path.isdir(path) or os.path.basename(path).startswith("."): |
| 202 | + return False |
| 203 | + if sys.platform == "darwin": |
| 204 | + return not (os.stat(path).st_mode & UF_HIDDEN) |
| 205 | + if sys.platform == "win32": |
| 206 | + st_file_attributes = os.stat(path).st_file_attributes |
| 207 | + return not ( |
| 208 | + (st_file_attributes & FILE_ATTRIBUTE_SYSTEM) |
| 209 | + | (st_file_attributes & FILE_ATTRIBUTE_HIDDEN) |
| 210 | + ) |
| 211 | + |
| 212 | + |
| 213 | +def __get_images_from_directory(directory: StrPath): |
| 214 | + """Returns a list of AutoSplitImage parsed from a directory. |
| 215 | + Hidden files, system files and folders are silently ignored.""" |
| 216 | + file_paths = ( |
| 217 | + os.path.join(directory, filename) # format: skip |
| 218 | + for filename in os.listdir(directory) |
| 219 | + ) |
| 220 | + filtered_image_paths = ( |
| 221 | + image_path # format: skip |
| 222 | + for image_path in file_paths |
| 223 | + if is_user_file(image_path) |
| 224 | + ) |
| 225 | + return [AutoSplitImage(image_path) for image_path in filtered_image_paths] |
202 | 226 |
|
| 227 | + |
| 228 | +def parse_and_validate_images(autosplit: "AutoSplit"): |
| 229 | + all_images = __get_images_from_directory( |
| 230 | + autosplit.settings_dict["split_image_directory"] |
| 231 | + ) |
203 | 232 | # Find non-split images and then remove them from the list |
204 | 233 | start_image = __pop_image_type(all_images, ImageType.START) |
205 | 234 | reset_image = __pop_image_type(all_images, ImageType.RESET) |
@@ -245,12 +274,16 @@ def parse_and_validate_images(autosplit: "AutoSplit"): |
245 | 274 |
|
246 | 275 | # Check that there's only one Reset Image |
247 | 276 | if image.image_type == ImageType.RESET: |
248 | | - error_message = lambda: error_messages.multiple_keyword_images(RESET_KEYWORD) # noqa: E731 |
| 277 | + error_message = lambda: error_messages.multiple_keyword_images( |
| 278 | + RESET_KEYWORD |
| 279 | + ) # noqa: E731 |
249 | 280 | break |
250 | 281 |
|
251 | 282 | # Check that there's only one Start Image |
252 | 283 | if image.image_type == ImageType.START: |
253 | | - error_message = lambda: error_messages.multiple_keyword_images(START_KEYWORD) # noqa: E731 |
| 284 | + error_message = lambda: error_messages.multiple_keyword_images( |
| 285 | + START_KEYWORD |
| 286 | + ) # noqa: E731 |
254 | 287 | break |
255 | 288 |
|
256 | 289 | if error_message: |
|
0 commit comments