python-fitparse 2.8.0__tar.gz → 2.10.0__tar.gz
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.
- {python_fitparse-2.8.0 → python_fitparse-2.10.0}/PKG-INFO +1 -1
- {python_fitparse-2.8.0 → python_fitparse-2.10.0}/fitparse/base.py +23 -4
- {python_fitparse-2.8.0 → python_fitparse-2.10.0}/fitparse/processors.py +3 -3
- {python_fitparse-2.8.0 → python_fitparse-2.10.0}/fitparse/records.py +7 -4
- {python_fitparse-2.8.0 → python_fitparse-2.10.0}/pyproject.toml +1 -1
- {python_fitparse-2.8.0 → python_fitparse-2.10.0}/.gitignore +0 -0
- {python_fitparse-2.8.0 → python_fitparse-2.10.0}/LICENSE +0 -0
- {python_fitparse-2.8.0 → python_fitparse-2.10.0}/README.md +0 -0
- {python_fitparse-2.8.0 → python_fitparse-2.10.0}/fitparse/__init__.py +0 -0
- {python_fitparse-2.8.0 → python_fitparse-2.10.0}/fitparse/profile.py +0 -0
- {python_fitparse-2.8.0 → python_fitparse-2.10.0}/fitparse/utils.py +0 -0
- {python_fitparse-2.8.0 → python_fitparse-2.10.0}/patches/message_types/location.py +0 -0
- {python_fitparse-2.8.0 → python_fitparse-2.10.0}/patches/message_types/stress_level.py +0 -0
- {python_fitparse-2.8.0 → python_fitparse-2.10.0}/scripts/fitdump +0 -0
- {python_fitparse-2.8.0 → python_fitparse-2.10.0}/scripts/generate_profile.py +0 -0
- {python_fitparse-2.8.0 → python_fitparse-2.10.0}/scripts/unit_tool.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: python-fitparse
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.10.0
|
|
4
4
|
Summary: Python library to parse ANT/Garmin .FIT files
|
|
5
5
|
Project-URL: Homepage, https://github.com/nbr23/python-fitparse
|
|
6
6
|
Project-URL: Repository, https://github.com/nbr23/python-fitparse
|
|
@@ -62,10 +62,28 @@ class DeveloperDataMixin:
|
|
|
62
62
|
dev_data_index = message.get_raw_value('developer_data_index')
|
|
63
63
|
field_def_num = message.get_raw_value('field_definition_number')
|
|
64
64
|
base_type_id = message.get_raw_value('fit_base_type_id')
|
|
65
|
-
field_name = message.get_raw_value('field_name')
|
|
65
|
+
field_name = message.get_raw_value('field_name')
|
|
66
66
|
units = message.get_raw_value("units")
|
|
67
67
|
native_field_num = message.get_raw_value('native_field_num')
|
|
68
68
|
|
|
69
|
+
for name, value in (('developer_data_index', dev_data_index),
|
|
70
|
+
('field_definition_number', field_def_num),
|
|
71
|
+
('fit_base_type_id', base_type_id)):
|
|
72
|
+
if not isinstance(value, int):
|
|
73
|
+
raise FitParseError(
|
|
74
|
+
"Invalid %s=%r in developer field description" % (name, value))
|
|
75
|
+
if not isinstance(field_name, str) or not field_name:
|
|
76
|
+
field_name = "unnamed_dev_field_%s" % field_def_num
|
|
77
|
+
if not isinstance(units, str):
|
|
78
|
+
units = None
|
|
79
|
+
base_type = BASE_TYPES.get(base_type_id)
|
|
80
|
+
if base_type is None:
|
|
81
|
+
warnings.warn(
|
|
82
|
+
"Unknown base type %d for developer field %d; falling back to byte encoding."
|
|
83
|
+
% (base_type_id, field_def_num)
|
|
84
|
+
)
|
|
85
|
+
base_type = BASE_TYPE_BYTE
|
|
86
|
+
|
|
69
87
|
if dev_data_index not in self.dev_types:
|
|
70
88
|
if self.check_developer_data:
|
|
71
89
|
raise FitParseError("No such dev_data_index=%s found" % (dev_data_index))
|
|
@@ -81,7 +99,7 @@ class DeveloperDataMixin:
|
|
|
81
99
|
fields[field_def_num] = DevField(
|
|
82
100
|
dev_data_index=dev_data_index,
|
|
83
101
|
def_num=field_def_num,
|
|
84
|
-
type=
|
|
102
|
+
type=base_type,
|
|
85
103
|
name=field_name,
|
|
86
104
|
units=units,
|
|
87
105
|
native_field_num=native_field_num
|
|
@@ -296,7 +314,8 @@ class FitFileDecoder(DeveloperDataMixin):
|
|
|
296
314
|
if (field_size % base_type.size) != 0:
|
|
297
315
|
warnings.warn(
|
|
298
316
|
"Invalid field size %d for field '%s' of type '%s' (expected a multiple of %d); falling back to byte encoding." % (
|
|
299
|
-
|
|
317
|
+
field_size, field.name if field else 'unknown_%d' % field_def_num,
|
|
318
|
+
base_type.name, base_type.size)
|
|
300
319
|
)
|
|
301
320
|
base_type = BASE_TYPE_BYTE
|
|
302
321
|
|
|
@@ -470,7 +489,7 @@ class FitFileDecoder(DeveloperDataMixin):
|
|
|
470
489
|
value = raw_value
|
|
471
490
|
|
|
472
491
|
# Update compressed timestamp field
|
|
473
|
-
if (field_def.def_num == FIELD_TYPE_TIMESTAMP.def_num) and (raw_value
|
|
492
|
+
if (field_def.def_num == FIELD_TYPE_TIMESTAMP.def_num) and isinstance(raw_value, int):
|
|
474
493
|
self._compressed_ts_accumulator = raw_value
|
|
475
494
|
|
|
476
495
|
field_datas.append(
|
|
@@ -69,12 +69,12 @@ class FitFileDataProcessor:
|
|
|
69
69
|
|
|
70
70
|
def process_type_date_time(self, field_data):
|
|
71
71
|
value = field_data.value
|
|
72
|
-
if value
|
|
72
|
+
if isinstance(value, int) and value >= 0x10000000:
|
|
73
73
|
field_data.value = datetime.datetime.fromtimestamp(timestamp=(UTC_REFERENCE + value), tz=datetime.timezone.utc).replace(tzinfo=None)
|
|
74
74
|
field_data.units = None # Units were 's', set to None
|
|
75
75
|
|
|
76
76
|
def process_type_local_date_time(self, field_data):
|
|
77
|
-
if field_data.value
|
|
77
|
+
if isinstance(field_data.value, int):
|
|
78
78
|
# NOTE: This value was created on the device using it's local timezone.
|
|
79
79
|
# Unless we know that timezone, this value won't be correct. However, if we
|
|
80
80
|
# assume UTC, at least it'll be consistent.
|
|
@@ -82,7 +82,7 @@ class FitFileDataProcessor:
|
|
|
82
82
|
field_data.units = None
|
|
83
83
|
|
|
84
84
|
def process_type_localtime_into_day(self, field_data):
|
|
85
|
-
if field_data.value
|
|
85
|
+
if isinstance(field_data.value, int):
|
|
86
86
|
# NOTE: Values larger or equal to 86400 should not be possible.
|
|
87
87
|
# Additionally, if the value is exactly 86400, it will lead to an error when trying to
|
|
88
88
|
# create the time with datetime.time(24, 0 , 0).
|
|
@@ -316,6 +316,9 @@ class ComponentField(RecordBase):
|
|
|
316
316
|
if self.bit_offset and self.bit_offset >= len(raw_value) << 3:
|
|
317
317
|
raise ValueError()
|
|
318
318
|
|
|
319
|
+
if not all(isinstance(value, int) for value in raw_value):
|
|
320
|
+
return None
|
|
321
|
+
|
|
319
322
|
unpacked_num = 0
|
|
320
323
|
|
|
321
324
|
# Unpack byte array as little endian
|
|
@@ -324,11 +327,11 @@ class ComponentField(RecordBase):
|
|
|
324
327
|
|
|
325
328
|
raw_value = unpacked_num
|
|
326
329
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
raw_value = (raw_value >> self.bit_offset) & ((1 << self.bits) - 1)
|
|
330
|
+
if not isinstance(raw_value, int):
|
|
331
|
+
return None
|
|
330
332
|
|
|
331
|
-
|
|
333
|
+
# Mask and shift like a normal number
|
|
334
|
+
return (raw_value >> self.bit_offset) & ((1 << self.bits) - 1)
|
|
332
335
|
|
|
333
336
|
|
|
334
337
|
class Crc:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|