pumaguard 20.post192__py3-none-any.whl → 20.post229__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pumaguard/main.py +29 -15
- pumaguard/model_downloader.py +1 -1
- pumaguard/presets.py +19 -4
- pumaguard/pumaguard-ui/assets/NOTICES +297 -206
- pumaguard/pumaguard-ui/assets/fonts/MaterialIcons-Regular.otf +0 -0
- pumaguard/pumaguard-ui/flutter_bootstrap.js +1 -1
- pumaguard/pumaguard-ui/flutter_service_worker.js +6 -6
- pumaguard/pumaguard-ui/main.dart.js +54897 -52616
- pumaguard/pumaguard-ui/main.dart.mjs +182 -175
- pumaguard/pumaguard-ui/main.dart.wasm +0 -0
- pumaguard/server.py +4 -4
- pumaguard/web_routes/diagnostics.py +13 -2
- pumaguard/web_routes/directories.py +6 -0
- pumaguard/web_routes/folders.py +66 -15
- pumaguard/web_routes/photos.py +30 -8
- pumaguard/web_routes/settings.py +147 -0
- pumaguard/web_routes/sync.py +62 -13
- pumaguard/web_ui.py +13 -1
- {pumaguard-20.post192.dist-info → pumaguard-20.post229.dist-info}/METADATA +29 -2
- {pumaguard-20.post192.dist-info → pumaguard-20.post229.dist-info}/RECORD +24 -24
- {pumaguard-20.post192.dist-info → pumaguard-20.post229.dist-info}/WHEEL +0 -0
- {pumaguard-20.post192.dist-info → pumaguard-20.post229.dist-info}/entry_points.txt +0 -0
- {pumaguard-20.post192.dist-info → pumaguard-20.post229.dist-info}/licenses/LICENSE +0 -0
- {pumaguard-20.post192.dist-info → pumaguard-20.post229.dist-info}/top_level.txt +0 -0
pumaguard/main.py
CHANGED
|
@@ -50,6 +50,12 @@ def create_global_parser() -> argparse.ArgumentParser:
|
|
|
50
50
|
choices=["bash"],
|
|
51
51
|
help="Print out bash completion script",
|
|
52
52
|
)
|
|
53
|
+
global_parser.add_argument(
|
|
54
|
+
"--log-file",
|
|
55
|
+
help="Path to log file (default: ~/.cache/pumaguard/pumaguard.log)",
|
|
56
|
+
type=str,
|
|
57
|
+
default=None,
|
|
58
|
+
)
|
|
53
59
|
global_parser.add_argument(
|
|
54
60
|
"--model-path",
|
|
55
61
|
help="Where the models are stored (default = %(default)s)",
|
|
@@ -183,19 +189,7 @@ def main():
|
|
|
183
189
|
logging.basicConfig(level=logging.INFO)
|
|
184
190
|
logger = logging.getLogger("PumaGuard")
|
|
185
191
|
|
|
186
|
-
#
|
|
187
|
-
log_dir = get_xdg_cache_home() / "pumaguard"
|
|
188
|
-
log_dir.mkdir(parents=True, exist_ok=True)
|
|
189
|
-
log_file = log_dir / "pumaguard.log"
|
|
190
|
-
|
|
191
|
-
file_handler = logging.FileHandler(str(log_file))
|
|
192
|
-
file_handler.setLevel(logging.DEBUG)
|
|
193
|
-
formatter = logging.Formatter(
|
|
194
|
-
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
195
|
-
)
|
|
196
|
-
file_handler.setFormatter(formatter)
|
|
197
|
-
logger.addHandler(file_handler)
|
|
198
|
-
|
|
192
|
+
# Parse args early to get log file location
|
|
199
193
|
global_args_parser = create_global_parser()
|
|
200
194
|
parser = argparse.ArgumentParser(
|
|
201
195
|
description="""The goal of this project is to accurately classify
|
|
@@ -205,11 +199,31 @@ def main():
|
|
|
205
199
|
dataset and validated using a separate set of images.""",
|
|
206
200
|
parents=[global_args_parser],
|
|
207
201
|
)
|
|
208
|
-
|
|
209
202
|
configure_subparsers(parser, global_args_parser)
|
|
210
|
-
|
|
211
203
|
args = parser.parse_args()
|
|
212
204
|
|
|
205
|
+
# Determine log file location
|
|
206
|
+
if args.log_file:
|
|
207
|
+
log_file = args.log_file
|
|
208
|
+
# Ensure parent directory exists
|
|
209
|
+
log_dir = os.path.dirname(log_file)
|
|
210
|
+
if log_dir:
|
|
211
|
+
os.makedirs(log_dir, exist_ok=True)
|
|
212
|
+
else:
|
|
213
|
+
# Store logs in XDG cache directory (default)
|
|
214
|
+
log_dir = get_xdg_cache_home() / "pumaguard"
|
|
215
|
+
log_dir.mkdir(parents=True, exist_ok=True)
|
|
216
|
+
log_file = str(log_dir / "pumaguard.log")
|
|
217
|
+
|
|
218
|
+
file_handler = logging.FileHandler(log_file)
|
|
219
|
+
file_handler.setLevel(logging.DEBUG)
|
|
220
|
+
formatter = logging.Formatter(
|
|
221
|
+
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
222
|
+
)
|
|
223
|
+
file_handler.setFormatter(formatter)
|
|
224
|
+
logger.addHandler(file_handler)
|
|
225
|
+
logger.info("Logging to: %s", log_file)
|
|
226
|
+
|
|
213
227
|
if args.debug:
|
|
214
228
|
logger.setLevel(logging.DEBUG)
|
|
215
229
|
|
pumaguard/model_downloader.py
CHANGED
|
@@ -23,7 +23,7 @@ import yaml
|
|
|
23
23
|
|
|
24
24
|
logger = logging.getLogger("PumaGuard")
|
|
25
25
|
|
|
26
|
-
MODEL_TAG = "
|
|
26
|
+
MODEL_TAG = "82ec09d65cabd06d46aeefed3a0317200888367d"
|
|
27
27
|
MODEL_BASE_URI = (
|
|
28
28
|
"https://github.com/PEEC-Nature-Youth-Group/pumaguard-models/raw"
|
|
29
29
|
)
|
pumaguard/presets.py
CHANGED
|
@@ -120,7 +120,7 @@ class Preset:
|
|
|
120
120
|
self.settings_file = get_default_settings_file()
|
|
121
121
|
self.yolo_min_size = 0.02
|
|
122
122
|
self.yolo_conf_thresh = 0.25
|
|
123
|
-
self.yolo_max_dets =
|
|
123
|
+
self.yolo_max_dets = 2
|
|
124
124
|
self.yolo_model_filename = "yolov8s_101425.pt"
|
|
125
125
|
self.classifier_model_filename = "colorbw_111325.h5"
|
|
126
126
|
self.alpha = 1e-5
|
|
@@ -130,7 +130,7 @@ class Preset:
|
|
|
130
130
|
self.sound_path = os.path.join(
|
|
131
131
|
os.path.dirname(__file__), "../pumaguard-sounds"
|
|
132
132
|
)
|
|
133
|
-
self.deterrent_sound_file = "
|
|
133
|
+
self.deterrent_sound_file = "deterrent_puma.mp3"
|
|
134
134
|
self.verification_path = "data/stable/stable_test"
|
|
135
135
|
self.batch_size = 16
|
|
136
136
|
self.notebook_number = 1
|
|
@@ -196,7 +196,22 @@ class Preset:
|
|
|
196
196
|
)
|
|
197
197
|
return
|
|
198
198
|
except yaml.constructor.ConstructorError as e:
|
|
199
|
-
|
|
199
|
+
error_msg = str(e)
|
|
200
|
+
if "python/tuple" in error_msg:
|
|
201
|
+
raise PresetError(
|
|
202
|
+
f"{error_msg}\n\n"
|
|
203
|
+
"Your settings file contains Python-specific tuple "
|
|
204
|
+
"formatting that is no longer supported.\n"
|
|
205
|
+
f"Please update {filename} to use YAML list syntax.\n"
|
|
206
|
+
"For example, change:\n"
|
|
207
|
+
" image-dimensions: !!python/tuple [512, 512]\n"
|
|
208
|
+
"to:\n"
|
|
209
|
+
" image-dimensions:\n"
|
|
210
|
+
" - 512\n"
|
|
211
|
+
" - 512\n"
|
|
212
|
+
"Or delete the file to use defaults."
|
|
213
|
+
) from e
|
|
214
|
+
raise PresetError(error_msg) from e
|
|
200
215
|
|
|
201
216
|
self.yolo_min_size = settings.get("YOLO-min-size", 0.02)
|
|
202
217
|
self.yolo_conf_thresh = settings.get("YOLO-conf-thresh", 0.25)
|
|
@@ -308,7 +323,7 @@ class Preset:
|
|
|
308
323
|
"color-mode": self.color_mode,
|
|
309
324
|
"file-stabilization-extra-wait": self.file_stabilization_extra_wait,
|
|
310
325
|
"epochs": self.epochs,
|
|
311
|
-
"image-dimensions": self.image_dimensions,
|
|
326
|
+
"image-dimensions": list(self.image_dimensions),
|
|
312
327
|
"lion-directories": self.lion_directories,
|
|
313
328
|
"validation-lion-directories": self.validation_lion_directories,
|
|
314
329
|
"model-function": self.model_function_name,
|