• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Olezhich / CueTools / 26340928174

23 May 2026 06:59PM UTC coverage: 90.099%. First build
26340928174

Pull #41

github

web-flow
Merge 253d9e1e8 into 8c5bf4989
Pull Request #41: support of catalog and flags keywords added

5 of 6 new or added lines in 2 files covered. (83.33%)

364 of 404 relevant lines covered (90.1%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.83
/cuetools/parser/parser.py
1
from pathlib import Path
1✔
2
from typing import Iterator
1✔
3
from cuetools.models import AlbumData, TrackData
1✔
4
from cuetools.parser.errors import CueParseError, CueValidationError
1✔
5
from cuetools.parser.handlers import title_case_handler
1✔
6
from cuetools.parser.lex import Token, lex
1✔
7

8
WAVE_EXTENSIONS = ['.flac', '.ape', '.wav']
1✔
9

10

11
def load_f_iter(cue: Iterator[str], strict_title_case: bool = False) -> AlbumData:
1✔
12
    """loading an object from an iterator"""
13
    album = AlbumData()
1✔
14
    current_file = None
1✔
15
    current_track = None
1✔
16

17
    current_line = 0
1✔
18

19
    for line in cue:
1✔
20
        current_line += 1
1✔
21
        tokens = [i for i in lex(line)]
1✔
22
        try:
1✔
23
            match tokens[0].type:
1✔
24
                case Token.PERFORMER:
1✔
25
                    performer = tokens[1]
1✔
26
                    if not current_track:
1✔
27
                        title_case_handler(
1✔
28
                            performer,
29
                            strict_title_case,
30
                            lambda x: setattr(album, 'performer', x),
31
                            album.set_performer,
32
                            current_line,
33
                            line,
34
                            'album performer name',
35
                        )
36
                    else:
37
                        title_case_handler(
×
38
                            performer,
39
                            strict_title_case,
40
                            lambda x: setattr(current_track, 'performer', x),
41
                            current_track.set_performer,
42
                            current_line,
43
                            line,
44
                            'track performer name',
45
                        )
46
                case Token.TITLE:
1✔
47
                    title = tokens[1]
1✔
48
                    if not current_track:
1✔
49
                        title_case_handler(
1✔
50
                            title,
51
                            strict_title_case,
52
                            lambda x: setattr(album, 'title', x),
53
                            album.set_title,
54
                            current_line,
55
                            line,
56
                            'album title',
57
                        )
58
                    else:
59
                        title_case_handler(
1✔
60
                            title,
61
                            strict_title_case,
62
                            lambda x: setattr(current_track, 'title', x),
63
                            current_track.set_title,
64
                            current_line,
65
                            line,
66
                            'track title',
67
                        )
68
                case Token.FILE:
1✔
69
                    filepath = tokens[1]
1✔
70
                    match filepath.type:
1✔
71
                        case Token.ARG_QUOTES:
1✔
72
                            file_type = tokens[2]
1✔
73
                            match file_type.type:
1✔
74
                                case Token.WAVE:
1✔
75
                                    if not any(
1✔
76
                                        filepath.lexeme.endswith(ext)
77
                                        for ext in WAVE_EXTENSIONS
78
                                    ):
79
                                        raise CueParseError(
1✔
80
                                            current_line,
81
                                            line,
82
                                            f"""current WAVE file type like {', '.join(f"'{i}'" for i in WAVE_EXTENSIONS)}""",
83
                                            file_type.lexeme,
84
                                            file_type.pos,
85
                                        )
86
                                case _:
×
87
                                    raise CueParseError(
×
88
                                        current_line,
89
                                        line,
90
                                        'file type tag',
91
                                        file_type.lexeme,
92
                                        file_type.pos,
93
                                    )
94

95
                            current_file = (  # noqa: F841 # type: ignore
1✔
96
                                Path(filepath.lexeme),
97
                                current_line,
98
                                line,
99
                                filepath.pos,
100
                                filepath.lexeme,
101
                            )
102
                        case _:
×
103
                            CueParseError(
×
104
                                current_line,
105
                                line,
106
                                'audiofile path',
107
                                filepath.lexeme,
108
                                filepath.pos,
109
                            )
110
                case Token.ISRC:
1✔
111
                    ...
1✔
112
                case Token.PREGAP:
1✔
113
                    ...
×
114
                case Token.CATALOG:
1✔
NEW
115
                    ...
×
116
                case Token.FLAGS:
1✔
117
                    ...
1✔
118
                case Token.REM:
1✔
119
                    rem_type = tokens[1]
1✔
120
                    value = tokens[2]
1✔
121
                    match rem_type.type:
1✔
122
                        case Token.GENRE:
1✔
123
                            title_case_handler(
1✔
124
                                value,
125
                                strict_title_case,
126
                                lambda x: setattr(album.rem, 'genre', x),
127
                                album.rem.set_genre,
128
                                current_line,
129
                                line,
130
                                'album genre',
131
                            )
132
                        case Token.DATE:
1✔
133
                            try:
1✔
134
                                album.rem.date = int(value.lexeme)
1✔
135
                            except ValueError as e:
1✔
136
                                raise CueValidationError(
1✔
137
                                    current_line, line, value.pos, value.lexeme, e
138
                                )
139
                        case Token.REPLAYGAIN_ALBUM_GAIN:
1✔
140
                            try:
1✔
141
                                album.rem.replaygain_gain = value.lexeme  # type: ignore[assignment]
1✔
142
                            except ValueError as e:
1✔
143
                                raise CueValidationError(
1✔
144
                                    current_line, line, value.pos, value.lexeme, e
145
                                )
146
                        case Token.REPLAYGAIN_ALBUM_PEAK:
1✔
147
                            try:
1✔
148
                                album.rem.replaygain_peak = value.lexeme  # type: ignore[assignment]
1✔
149
                            except ValueError as e:
×
150
                                raise CueValidationError(
×
151
                                    current_line, line, value.pos, value.lexeme, e
152
                                )
153
                        case Token.REPLAYGAIN_TRACK_GAIN:
1✔
154
                            if not current_track:
1✔
155
                                raise CueParseError(
×
156
                                    current_line,
157
                                    line,
158
                                    'any TRACK tag before',
159
                                    tokens[0].lexeme,
160
                                    tokens[1].pos,
161
                                )
162
                            try:
1✔
163
                                current_track.rem.replaygain_gain = value.lexeme  # type: ignore[assignment]
1✔
164
                            except ValueError as e:
×
165
                                raise CueValidationError(
×
166
                                    current_line, line, value.pos, value.lexeme, e
167
                                )
168
                        case Token.REPLAYGAIN_TRACK_PEAK:
1✔
169
                            if not current_track:
1✔
170
                                raise CueParseError(
×
171
                                    current_line,
172
                                    line,
173
                                    'any TRACK tag before',
174
                                    tokens[0].lexeme,
175
                                    tokens[1].pos,
176
                                )
177
                            try:
1✔
178
                                current_track.rem.replaygain_peak = value.lexeme  # type: ignore[assignment]
1✔
179
                            except ValueError as e:
×
180
                                raise CueValidationError(
×
181
                                    current_line, line, value.pos, value.lexeme, e
182
                                )
183
                        case Token.DISCID:
1✔
184
                            ...
1✔
185
                        case Token.COMMENT:
1✔
186
                            ...
1✔
187
                        case Token.COMPOSER:
1✔
188
                            ...
1✔
189
                        case _:
×
190
                            raise CueParseError(
1✔
191
                                current_line,
192
                                line,
193
                                'Correct REM parameter',
194
                                rem_type.lexeme,
195
                                rem_type.pos,
196
                            )
197
                case Token.TRACK:
1✔
198
                    if not current_file:
1✔
199
                        raise CueParseError(
×
200
                            current_line,
201
                            line,
202
                            'any FILE tag before',
203
                            tokens[1].lexeme,
204
                            tokens[0].pos,
205
                        )
206
                    if len(tokens) < 2 or tokens[1].type != Token.AUDIO:
1✔
207
                        raise CueParseError(
×
208
                            current_line,
209
                            line,
210
                            'AUDIO tag',
211
                            tokens[1].lexeme if len(tokens) > 1 else 'Nothing',
212
                            tokens[0].pos,
213
                        )
214
                    if current_track:
1✔
215
                        try:
1✔
216
                            album.add_track(current_track)
1✔
217
                        except ValueError as e:
×
218
                            raise CueValidationError(
×
219
                                current_line, line, 0, 'Invalid previous track', e
220
                            )
221
                    current_track = TrackData(
1✔
222
                        track=int(tokens[0].lexeme),
223
                        file=current_file[0],
224
                    )
225
                case Token.INDEX:
1✔
226
                    if not current_track:
1✔
227
                        raise CueParseError(
1✔
228
                            current_line,
229
                            line,
230
                            'any TRACK tag before',
231
                            tokens[0].lexeme,
232
                            tokens[1].pos,
233
                        )
234
                    index_type = int(tokens[0].lexeme)
1✔
235
                    if index_type == 0:
1✔
236
                        if current_track.index00:
1✔
237
                            raise CueParseError(
×
238
                                current_line,
239
                                line,
240
                                'one INDEX 00 value',
241
                                'dublicate INDEX 00 value',
242
                                tokens[0].pos,
243
                            )
244
                        current_track.index00 = tokens[1].lexeme  # type: ignore[assignment]
1✔
245
                    elif index_type == 1:
1✔
246
                        current_track.index01 = tokens[1].lexeme  # type: ignore[assignment]
1✔
247
                case _:
×
248
                    raise CueParseError(
×
249
                        current_line,
250
                        line,
251
                        'Correct CUE keyword',
252
                        tokens[0].lexeme,
253
                        tokens[0].pos,
254
                    )
255
        except IndexError:
1✔
256
            raise CueParseError(
1✔
257
                current_line, line, 'More tokens to parse the string correctly', line, 0
258
            )
259

260
    if current_track:
1✔
261
        album.add_track(current_track)
1✔
262

263
    return album
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc