hytek-parser 2.1.0__tar.gz → 2.3.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.
Files changed (28) hide show
  1. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/PKG-INFO +1 -1
  2. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/__init__.py +3 -1
  3. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/hy3/line_parsers/__init__.py +2 -1
  4. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/hy3/line_parsers/b_meet_parsers.py +2 -0
  5. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/hy3/line_parsers/d_swimmer_parsers.py +5 -2
  6. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/hy3/line_parsers/e_event_parsers.py +3 -1
  7. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/hy3/line_parsers/h_dq_parsers.py +28 -0
  8. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/hy3/schemas.py +20 -2
  9. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/pyproject.toml +1 -1
  10. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/LICENSE.md +0 -0
  11. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/README.md +0 -0
  12. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/_utils.py +0 -0
  13. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/export_xls/__init__.py +0 -0
  14. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/export_xls/_utils.py +0 -0
  15. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/export_xls/schemas.py +0 -0
  16. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/hy3/__init__.py +0 -0
  17. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/hy3/_utils.py +0 -0
  18. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/hy3/enums.py +0 -0
  19. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/hy3/line_parsers/a_file_parsers.py +0 -0
  20. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/hy3/line_parsers/c_team_parsers.py +0 -0
  21. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/hy3/line_parsers/f_relay_parsers.py +0 -0
  22. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/hy3/line_parsers/g_split_parsers.py +0 -0
  23. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/hy3_parser.py +0 -0
  24. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/hyv/__init__.py +0 -0
  25. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/hyv/enums.py +0 -0
  26. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/hyv/schemas.py +0 -0
  27. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/py.typed +0 -0
  28. {hytek_parser-2.1.0 → hytek_parser-2.3.0}/hytek_parser/types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hytek-parser
3
- Version: 2.1.0
3
+ Version: 2.3.0
4
4
  Summary: Parsers for the files produced by Hytek's Meet Manager.
5
5
  Home-page: https://www.github.com/SwimComm/hytek-parser
6
6
  License: MIT
@@ -1,4 +1,6 @@
1
1
  """A Hytek hy3 file parser."""
2
+ from importlib.metadata import version
3
+
2
4
  from .export_xls import ExportXlsParseError, parse_event_export_xls
3
5
  from .hy3 import HY3_LINE_PARSERS
4
6
  from .hy3_parser import parse_hy3
@@ -15,4 +17,4 @@ __all__ = [
15
17
  ]
16
18
  __author__ = "Nino Maruszewski"
17
19
  __license__ = "MIT"
18
- __version__ = "2.1.0"
20
+ __version__ = version(__package__)
@@ -9,7 +9,7 @@ from .d_swimmer_parsers import d1_parser
9
9
  from .e_event_parsers import e1_parser, e2_parser
10
10
  from .f_relay_parsers import f1_parser, f2_parser, f3_parser
11
11
  from .g_split_parsers import g1_parser
12
- from .h_dq_parsers import h1_parser
12
+ from .h_dq_parsers import h1_parser, h2_parser
13
13
 
14
14
  __all__ = ["HY3_LINE_PARSERS"]
15
15
 
@@ -38,4 +38,5 @@ HY3_LINE_PARSERS: dict[
38
38
  "G1": g1_parser,
39
39
  # DQ info
40
40
  "H1": h1_parser,
41
+ "H2": h2_parser,
41
42
  }
@@ -33,6 +33,8 @@ def b2_parser(
33
33
  meet.masters = extract(line, 94, 2) == "06"
34
34
  meet.type_ = select_from_enum(MeetType, extract(line, 97, 2))
35
35
  meet.course = select_from_enum(Course, extract(line, 99, 1))
36
+ meet.notes = extract(line, 3, 45) or None
37
+ meet.sanction_number = extract(line, 109, 20) or None
36
38
 
37
39
  file.meet = meet
38
40
  return file
@@ -26,9 +26,12 @@ def d1_parser(
26
26
 
27
27
  # previously dropped D1 fields. Capture both per spec.
28
28
  # citizenship: cols 113-115 (3 chars). Observed: 'USA' or blank.
29
- # unparsed_d1_col_125: col 125 (1 char). Observed: 'N' or blank; semantics unverified.
29
+ # status: col 125 (1 char). Athlete status; observed 'N' (Normal) or blank.
30
30
  swimmer.citizenship = extract(line, 113, 3) or None
31
- swimmer.unparsed_d1_col_125 = extract(line, 125, 1) or None
31
+ swimmer.status = extract(line, 125, 1) or None
32
+ # class_year: cols 100-101 (2 chars). "Fr"/"So"/"Jr"/"Sr" school
33
+ # class in HS-meet exports; other data / blank in club exports.
34
+ swimmer.class_year = extract(line, 100, 2) or None
32
35
 
33
36
  swimmer.team_code = team_code
34
37
 
@@ -66,8 +66,9 @@ def e1_parser(
66
66
  # Meet Division: col 77-79 in most MM versions, col 92-93 in MM4/MM5-7.0Fa.
67
67
  # The two are mutually exclusive; col 77 takes precedence.
68
68
  meet_division = extract(line, 77, 3) or extract(line, 92, 2) or None
69
+ exhibition = extract(line, 84, 1) == "X"
69
70
 
70
- event.get_or_create_entry(
71
+ entry = event.get_or_create_entry(
71
72
  swimmers=entry_swimmers,
72
73
  relay=False,
73
74
  event_number=entry_event_number,
@@ -76,6 +77,7 @@ def e1_parser(
76
77
  converted_seed_time=entry_converted_seed_time,
77
78
  converted_seed_time_course=entry_converted_seed_time_course,
78
79
  meet_division=meet_division,
80
+ exhibition=exhibition,
79
81
  )
80
82
 
81
83
  # Update event
@@ -47,3 +47,31 @@ def h1_parser(
47
47
  file.meet.last_event = (event_num, event)
48
48
 
49
49
  return file
50
+
51
+
52
+ def h2_parser(
53
+ line: str, file: ParsedHytekFile, opts: dict[str, Any]
54
+ ) -> ParsedHytekFile:
55
+ """Parse an H2 line: the specific, human-readable DQ infraction detail.
56
+
57
+ Attaches the detail text to whichever DQ slot the preceding H1 populated
58
+ (finals -> swimoff -> prelim), mirroring h1_parser's resolution. Unlike H1,
59
+ the H2 2-char code is NOT asserted against the DQ code (it is a stroke/leg
60
+ sub-classification, not the same DisqualificationCode). No-op if no DQ slot
61
+ is set.
62
+ """
63
+ event_num, event = file.meet.last_event
64
+ entry = event.last_entry
65
+
66
+ detail = extract(line, 5, 124) or None
67
+
68
+ if entry.finals_dq_info:
69
+ entry.finals_dq_info.info_str_detail = detail
70
+ elif entry.swimoff_dq_info:
71
+ entry.swimoff_dq_info.info_str_detail = detail
72
+ elif entry.prelim_dq_info:
73
+ entry.prelim_dq_info.info_str_detail = detail
74
+
75
+ event.last_entry = entry
76
+ file.meet.last_event = (event_num, event)
77
+ return file
@@ -38,8 +38,14 @@ class Swimmer:
38
38
 
39
39
  # D1 fields previously dropped by the parser
40
40
  citizenship: Optional[str] = None
41
- # col 125; semantics unverified — name intentionally non-descriptive
42
- unparsed_d1_col_125: Optional[str] = None
41
+ # col 125; athlete status (Hytek MM "Status" field). Raw 1-char code — only
42
+ # "N" (Normal) or blank observed across ~9.25M records; other GUI statuses
43
+ # (Impaired/Exhibition/Foreigner/Rookie) never seen in data, so left as a
44
+ # raw code rather than an enum.
45
+ status: Optional[str] = None
46
+ # cols 100-101; "Fr"/"So"/"Jr"/"Sr" school class in HS-meet exports,
47
+ # other data / blank in club exports.
48
+ class_year: Optional[str] = None
43
49
 
44
50
 
45
51
  @define
@@ -78,6 +84,7 @@ class DisqualificationInfo:
78
84
 
79
85
  code: DisqualificationCode
80
86
  info_str: Optional[str] = None
87
+ info_str_detail: Optional[str] = None
81
88
 
82
89
 
83
90
  @define(init=False)
@@ -165,6 +172,7 @@ class EventEntry:
165
172
  # or numeric ('0'/'1'/'2'/'3'). Stored at cols 77-79 in most MM versions,
166
173
  # cols 92-93 in MM4/MM5-7.0Fa (read with col-77 precedence).
167
174
  meet_division: Optional[str] = None
175
+ exhibition: bool = False
168
176
 
169
177
  def __init__(
170
178
  self,
@@ -178,6 +186,7 @@ class EventEntry:
178
186
  relay_team_id: Optional[str] = None,
179
187
  relay_swim_team_code: Optional[str] = None,
180
188
  meet_division: Optional[str] = None,
189
+ exhibition: bool = False,
181
190
  ) -> None:
182
191
  self.swimmers = swimmers
183
192
  self.relay = relay
@@ -189,6 +198,7 @@ class EventEntry:
189
198
  self.relay_team_id = relay_team_id
190
199
  self.relay_swim_team_code = relay_swim_team_code
191
200
  self.meet_division = meet_division
201
+ self.exhibition = exhibition
192
202
 
193
203
  for course in ("prelim", "swimoff", "finals"):
194
204
  setattr(self, f"{course}_time", None)
@@ -277,6 +287,7 @@ class Event:
277
287
  relay_team_id: Optional[str] = None,
278
288
  relay_swim_team_code: Optional[str] = None,
279
289
  meet_division: Optional[str] = None,
290
+ exhibition: bool = False,
280
291
  ) -> EventEntry:
281
292
  """Get an event entry or create one if needed."""
282
293
  entry = EventEntry(
@@ -290,6 +301,7 @@ class Event:
290
301
  relay_team_id=relay_team_id,
291
302
  relay_swim_team_code=relay_swim_team_code,
292
303
  meet_division=meet_division,
304
+ exhibition=exhibition,
293
305
  )
294
306
  if self.entries and self.entries[-1].same_swimmer_entry_as(entry):
295
307
  # P/F entries always listed together: a swimmer (individuals) or a
@@ -336,6 +348,12 @@ class Meet:
336
348
  swimmers: dict[int, Swimmer]
337
349
  events: dict[str, Event]
338
350
 
351
+ # Extended info (optional; populated by later parser stages). Kept at the
352
+ # end of the field block (not next to `facility`/`country`) because attrs
353
+ # forbids a defaulted field preceding the non-default fields above.
354
+ sanction_number: Optional[str] = None
355
+ notes: Optional[str] = None
356
+
339
357
  # Bookeeping
340
358
  _last_team: tuple[str, Team] = field(default=None)
341
359
  _last_event: tuple[str, Event] = field(default=None)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "hytek-parser"
3
- version = "2.1.0"
3
+ version = "2.3.0"
4
4
  description = "Parsers for the files produced by Hytek's Meet Manager."
5
5
  license = "MIT"
6
6
  authors = ["Nino Maruszewski <nino.maruszewski@hotmail.com>"]
File without changes
File without changes