discid 1.6.0 → 1.7.0
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.
- checksums.yaml +4 -4
- data/CHANGES.md +8 -1
- data/README.md +10 -14
- data/examples/discfromtoc.rb +6 -5
- data/examples/discidinfo.rb +3 -3
- data/examples/parsetoc.rb +3 -3
- data/examples/readdiscid.rb +19 -13
- data/lib/discid/disc.rb +35 -42
- data/lib/discid/lib.rb +25 -23
- data/lib/discid/track.rb +13 -13
- data/lib/discid/version.rb +2 -2
- data/lib/discid.rb +27 -17
- data/test/helper.rb +7 -5
- data/test/test_disc.rb +10 -13
- data/test/test_discid.rb +36 -38
- data/test/test_lib.rb +2 -2
- data/test/test_track.rb +4 -4
- metadata +39 -29
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '09ccbdacc1ec0d20245f42d21311e6b7bd75ce43ccd2fcdc7b6b3463284f0530'
|
|
4
|
+
data.tar.gz: f7b0d5305393de17cc753962b9978cb90bb0f5a2d2261b3eee39cc1dd87f7df0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 681a9f92ac740b9c759bf33311446fbb4ccdc02273c820597853719454ffcafc8e29e0d881e633cc67387ed3bf513b4a001e61664837444c135fd2be48fcb254
|
|
7
|
+
data.tar.gz: 7ba59ea8196c6429604d591e621f3dc82f937bc7a3a8162d9c6282dedf680329b2a6f0d6e9023ca7d75c746423206b178d575bd62ee88f59191700686f21958b
|
data/CHANGES.md
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
|
+
## 1.7.0 (2026-08-13)
|
|
3
|
+
* Rename {DiscId.has_feature?} to {DiscId.feature?} ({DiscId.has_feature?} is still
|
|
4
|
+
provided as an alias, but deprecated)
|
|
5
|
+
* Fix fallback implementation of {DiscId::Disc#toc_string} for libdiscid < 0.6
|
|
6
|
+
* Clarify license in gemspec to be LGPL-3.0-or-later
|
|
7
|
+
* Code style cleanup for examples
|
|
8
|
+
|
|
2
9
|
## 1.6.0 (2025-05-09)
|
|
3
10
|
* Drop support for Ruby < 2.1
|
|
4
11
|
* Fixed license name in gemspec
|
|
@@ -10,7 +17,7 @@
|
|
|
10
17
|
* Removed support for Ruby 1.9
|
|
11
18
|
|
|
12
19
|
## 1.4.1 (2021-09-23)
|
|
13
|
-
* Fix Ruby 3 compatibility if {DiscId
|
|
20
|
+
* Fix Ruby 3 compatibility if {DiscId::Disc#tracks} gets called with a block
|
|
14
21
|
|
|
15
22
|
## 1.4.0 (2019-05-06)
|
|
16
23
|
* Fixed {DiscId.put} handling of first_track being > 1
|
data/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://phw.srht.site/ruby-discid/coverage/)
|
|
5
5
|
|
|
6
6
|
## About
|
|
7
|
-
ruby-discid provides Ruby bindings for the MusicBrainz DiscID library [libdiscid](
|
|
7
|
+
ruby-discid provides Ruby bindings for the MusicBrainz DiscID library [libdiscid](https://musicbrainz.org/doc/libdiscid).
|
|
8
8
|
It allows calculating DiscIDs (MusicBrainz and freedb) for Audio CDs. Additionally
|
|
9
9
|
the library can extract the MCN/UPC/EAN and the ISRCs from disc.
|
|
10
10
|
|
|
@@ -21,7 +21,7 @@ is documented in the [API documentation](https://www.rubydoc.info/gems/discid/).
|
|
|
21
21
|
|
|
22
22
|
## Installation
|
|
23
23
|
Before installing ruby-discid make sure you have libdiscid installed. See
|
|
24
|
-
|
|
24
|
+
https://musicbrainz.org/doc/libdiscid for more information on how to do this.
|
|
25
25
|
For Windows see also the notes below.
|
|
26
26
|
|
|
27
27
|
### Installing with RubyGems
|
|
@@ -29,12 +29,6 @@ Installing ruby-discid is best done using RubyGems:
|
|
|
29
29
|
|
|
30
30
|
gem install discid
|
|
31
31
|
|
|
32
|
-
### Installing from package repository
|
|
33
|
-
For some Linux distributions packages are available:
|
|
34
|
-
|
|
35
|
-
* [Arch Linux AUR package](https://aur.archlinux.org/packages/ruby-discid/)
|
|
36
|
-
* [Ubuntu PPA](https://launchpad.net/~musicbrainz-developers/+archive/ubuntu/stable)
|
|
37
|
-
|
|
38
32
|
### Install from source
|
|
39
33
|
You can also install from source. This requires RubyGems and Bundler installed.
|
|
40
34
|
First make sure you have installed bundler:
|
|
@@ -72,7 +66,7 @@ require 'discid'
|
|
|
72
66
|
|
|
73
67
|
# Specifying the device is optional. If omitted a platform
|
|
74
68
|
# specific default will be used.
|
|
75
|
-
device =
|
|
69
|
+
device = '/dev/cdrom'
|
|
76
70
|
disc = DiscId.read(device)
|
|
77
71
|
puts disc.id
|
|
78
72
|
```
|
|
@@ -82,7 +76,7 @@ puts disc.id
|
|
|
82
76
|
```ruby
|
|
83
77
|
require 'discid'
|
|
84
78
|
|
|
85
|
-
device =
|
|
79
|
+
device = '/dev/cdrom'
|
|
86
80
|
disc = DiscId.read(device, :mcn, :isrc)
|
|
87
81
|
|
|
88
82
|
# Print information about the disc:
|
|
@@ -94,9 +88,11 @@ puts "MCN : #{disc.mcn}"
|
|
|
94
88
|
# Print information about individual tracks:
|
|
95
89
|
disc.tracks do |track|
|
|
96
90
|
puts "Track ##{track.number}"
|
|
97
|
-
puts
|
|
98
|
-
|
|
99
|
-
|
|
91
|
+
puts format(' Length: %<minutes>02d:%<seconds>02d (%<sectors>i sectors)',
|
|
92
|
+
minutes: track.seconds / 60,
|
|
93
|
+
seconds: track.seconds % 60,
|
|
94
|
+
sectors: track.sectors)
|
|
95
|
+
puts " ISRC : #{track.isrc}"
|
|
100
96
|
end
|
|
101
97
|
```
|
|
102
98
|
|
|
@@ -111,7 +107,7 @@ Please report any issues on the
|
|
|
111
107
|
[issue tracker](https://todo.sr.ht/~phw/discid-bindings).
|
|
112
108
|
|
|
113
109
|
## License
|
|
114
|
-
ruby-discid Copyright (c) 2007-
|
|
110
|
+
ruby-discid Copyright (c) 2007-2026 by Philipp Wolfer <ph.wolfer@gmail.com>
|
|
115
111
|
|
|
116
112
|
ruby-discid is free software: you can redistribute it and/or modify
|
|
117
113
|
it under the terms of the GNU Lesser General Public License as published by
|
data/examples/discfromtoc.rb
CHANGED
|
@@ -9,16 +9,17 @@
|
|
|
9
9
|
|
|
10
10
|
# Just make sure we can run this example from the command
|
|
11
11
|
# line even if DiscId is not yet installed properly.
|
|
12
|
-
|
|
12
|
+
$LOAD_PATH << 'lib/' << 'ext/' << '../ext/' << '../lib/'
|
|
13
13
|
|
|
14
14
|
require 'discid'
|
|
15
15
|
|
|
16
|
-
offsets = [150,
|
|
16
|
+
offsets = [150, 44_942, 61_305, 72_755, 96_360, 130_485, 147_315, 164_275,
|
|
17
|
+
190_702, 205_412, 220_437]
|
|
17
18
|
|
|
18
|
-
disc = DiscId.put(1,
|
|
19
|
+
disc = DiscId.put(1, 242_457, offsets)
|
|
19
20
|
|
|
20
21
|
|
|
21
|
-
print <<
|
|
22
|
+
print <<OUT
|
|
22
23
|
|
|
23
24
|
Device : #{disc.device}
|
|
24
25
|
DiscID : #{disc.id}
|
|
@@ -30,4 +31,4 @@ Total length: #{disc.seconds} seconds
|
|
|
30
31
|
Sectors : #{disc.sectors}
|
|
31
32
|
|
|
32
33
|
Submit via #{disc.submission_url}
|
|
33
|
-
|
|
34
|
+
OUT
|
data/examples/discidinfo.rb
CHANGED
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
|
|
12
12
|
# Just make sure we can run this example from the command
|
|
13
13
|
# line even if DiscId is not yet installed properly.
|
|
14
|
-
|
|
14
|
+
$LOAD_PATH << 'lib/' << 'ext/' << '../ext/' << '../lib/'
|
|
15
15
|
|
|
16
16
|
require 'discid'
|
|
17
17
|
|
|
18
18
|
# Print information about libdiscid
|
|
19
|
-
print <<
|
|
19
|
+
print <<OUT
|
|
20
20
|
Version : #{DiscId::LIBDISCID_VERSION}
|
|
21
21
|
Default device : #{DiscId.default_device}
|
|
22
22
|
Supported features: #{DiscId.feature_list.join(', ')}
|
|
23
|
-
|
|
23
|
+
OUT
|
data/examples/parsetoc.rb
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
# Just make sure we can run this example from the command
|
|
11
11
|
# line even if DiscId is not yet installed properly.
|
|
12
|
-
|
|
12
|
+
$LOAD_PATH << 'lib/' << 'ext/' << '../ext/' << '../lib/'
|
|
13
13
|
|
|
14
14
|
require 'discid'
|
|
15
15
|
|
|
@@ -17,7 +17,7 @@ toc = '1 11 242457 150 44942 61305 72755 96360 130485 147315 164275 190702 20541
|
|
|
17
17
|
|
|
18
18
|
disc = DiscId.parse(toc)
|
|
19
19
|
|
|
20
|
-
print <<
|
|
20
|
+
print <<OUT
|
|
21
21
|
|
|
22
22
|
Device : #{disc.device}
|
|
23
23
|
DiscID : #{disc.id}
|
|
@@ -29,4 +29,4 @@ Total length: #{disc.seconds} seconds
|
|
|
29
29
|
Sectors : #{disc.sectors}
|
|
30
30
|
|
|
31
31
|
Submit via #{disc.submission_url}
|
|
32
|
-
|
|
32
|
+
OUT
|
data/examples/readdiscid.rb
CHANGED
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
|
|
12
12
|
# Just make sure we can run this example from the command
|
|
13
13
|
# line even if DiscId is not yet installed properly.
|
|
14
|
-
|
|
14
|
+
$LOAD_PATH << 'lib/' << 'ext/' << '../ext/' << '../lib/'
|
|
15
15
|
|
|
16
16
|
require 'discid'
|
|
17
17
|
|
|
18
18
|
# Read the device name from the command line or use the default.
|
|
19
|
-
device =
|
|
19
|
+
device = ARGV[0] || DiscId.default_device
|
|
20
20
|
|
|
21
21
|
# Create a new DiscID object and read the disc information.
|
|
22
22
|
# In case of errors exit the application.
|
|
@@ -25,14 +25,14 @@ begin
|
|
|
25
25
|
disc = DiscId.read(device, :isrc, :mcn)
|
|
26
26
|
|
|
27
27
|
# Instead of reading from a device we could set the TOC directly:
|
|
28
|
-
#disc = DiscId.put(1, 82255, [150, 16157, 35932, 57527])
|
|
28
|
+
# disc = DiscId.put(1, 82255, [150, 16157, 35932, 57527])
|
|
29
29
|
rescue DiscId::DiscError => e
|
|
30
30
|
puts e
|
|
31
31
|
exit(1)
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
# Print information about the disc:
|
|
35
|
-
print <<
|
|
35
|
+
print <<OUT
|
|
36
36
|
|
|
37
37
|
Device : #{disc.device}
|
|
38
38
|
DiscID : #{disc.id}
|
|
@@ -42,21 +42,27 @@ First track : #{disc.first_track_number}
|
|
|
42
42
|
Last track : #{disc.last_track_number}
|
|
43
43
|
Total length: #{disc.seconds} seconds
|
|
44
44
|
Sectors : #{disc.sectors}
|
|
45
|
-
|
|
45
|
+
OUT
|
|
46
46
|
|
|
47
|
-
puts "MCN : #{disc.mcn}" if DiscId.
|
|
47
|
+
puts "MCN : #{disc.mcn}" if DiscId.feature?(:mcn)
|
|
48
48
|
puts
|
|
49
49
|
|
|
50
50
|
# Print information about individual tracks:
|
|
51
51
|
disc.tracks do |track|
|
|
52
52
|
puts "Track ##{track.number}"
|
|
53
|
-
puts
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
puts
|
|
58
|
-
|
|
59
|
-
|
|
53
|
+
puts format(' Length: %<minutes>02d:%<seconds>02d (%<sectors>i sectors)',
|
|
54
|
+
minutes: track.seconds / 60,
|
|
55
|
+
seconds: track.seconds % 60,
|
|
56
|
+
sectors: track.sectors)
|
|
57
|
+
puts format(' Start : %<minutes>02d:%<seconds>02d (sector %<sector>i)',
|
|
58
|
+
minutes: track.start_time / 60,
|
|
59
|
+
seconds: track.start_time % 60,
|
|
60
|
+
sector: track.offset)
|
|
61
|
+
puts format(' End : %<minutes>02d:%<seconds>02d (sector %<sector>i)',
|
|
62
|
+
minutes: track.end_time / 60,
|
|
63
|
+
seconds: track.end_time % 60,
|
|
64
|
+
sector: track.end_sector)
|
|
65
|
+
puts " ISRC : #{track.isrc}" if DiscId.feature?(:isrc)
|
|
60
66
|
end
|
|
61
67
|
|
|
62
68
|
# Print a submission URL that can be used to submit
|
data/lib/discid/disc.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2013-2014, 2021 Philipp Wolfer
|
|
1
|
+
# Copyright (C) 2013-2014, 2021, 2025 Philipp Wolfer
|
|
2
2
|
#
|
|
3
3
|
# This program is free software: you can redistribute it and/or modify
|
|
4
4
|
# it under the terms of the GNU Lesser General Public License as published by
|
|
@@ -18,7 +18,6 @@ require 'discid/disc_error'
|
|
|
18
18
|
require 'discid/lib'
|
|
19
19
|
require 'discid/track'
|
|
20
20
|
|
|
21
|
-
#
|
|
22
21
|
module DiscId
|
|
23
22
|
# This class holds information about a disc (TOC, MCN, ISRCs).
|
|
24
23
|
#
|
|
@@ -41,7 +40,7 @@ module DiscId
|
|
|
41
40
|
@read = false
|
|
42
41
|
device = DiscId.default_device if device.nil?
|
|
43
42
|
|
|
44
|
-
|
|
43
|
+
unless device.respond_to? :to_s
|
|
45
44
|
raise TypeError, 'wrong argument type (expected String)'
|
|
46
45
|
end
|
|
47
46
|
|
|
@@ -49,11 +48,9 @@ module DiscId
|
|
|
49
48
|
flags = Lib.features_to_int features
|
|
50
49
|
result = Lib.read @handle, @device, flags
|
|
51
50
|
|
|
52
|
-
if result == 0
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
@read = true
|
|
56
|
-
end
|
|
51
|
+
raise DiscError, Lib.get_error_msg(@handle) if result == 0
|
|
52
|
+
|
|
53
|
+
@read = true
|
|
57
54
|
end
|
|
58
55
|
|
|
59
56
|
# @private
|
|
@@ -70,11 +67,9 @@ module DiscId
|
|
|
70
67
|
p.write_array_of_int(([sectors] + offsets)[0, 100])
|
|
71
68
|
result = Lib.put @handle, first_track, last_track, p
|
|
72
69
|
|
|
73
|
-
if result == 0
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
@read = true
|
|
77
|
-
end
|
|
70
|
+
raise DiscError, Lib.get_error_msg(@handle) if result == 0
|
|
71
|
+
|
|
72
|
+
@read = true
|
|
78
73
|
end
|
|
79
74
|
end
|
|
80
75
|
|
|
@@ -82,35 +77,35 @@ module DiscId
|
|
|
82
77
|
#
|
|
83
78
|
# @return [String] The DiscID or `nil` if no ID was yet read.
|
|
84
79
|
def id
|
|
85
|
-
|
|
80
|
+
Lib.get_id @handle if @read
|
|
86
81
|
end
|
|
87
82
|
|
|
88
83
|
# The FreeDB DiscID.
|
|
89
84
|
#
|
|
90
85
|
# @return [String] The DiscID or `nil` if no ID was yet read.
|
|
91
86
|
def freedb_id
|
|
92
|
-
|
|
87
|
+
Lib.get_freedb_id @handle if @read
|
|
93
88
|
end
|
|
94
89
|
|
|
95
90
|
# The number of the first track on this disc.
|
|
96
91
|
#
|
|
97
92
|
# @return [Integer] The number of the first track or `nil` if no ID was yet read.
|
|
98
93
|
def first_track_number
|
|
99
|
-
|
|
94
|
+
Lib.get_first_track_num @handle if @read
|
|
100
95
|
end
|
|
101
96
|
|
|
102
97
|
# The number of the last track on this disc.
|
|
103
98
|
#
|
|
104
99
|
# @return [Integer] The number of the last track or `nil` if no ID was yet read.
|
|
105
100
|
def last_track_number
|
|
106
|
-
|
|
101
|
+
Lib.get_last_track_num @handle if @read
|
|
107
102
|
end
|
|
108
103
|
|
|
109
104
|
# The length of the disc in sectors.
|
|
110
105
|
#
|
|
111
106
|
# @return [Integer] Sectors or `nil` if no ID was yet read.
|
|
112
107
|
def sectors
|
|
113
|
-
|
|
108
|
+
Lib.get_sectors @handle if @read
|
|
114
109
|
end
|
|
115
110
|
|
|
116
111
|
# The length of the disc in seconds.
|
|
@@ -127,11 +122,11 @@ module DiscId
|
|
|
127
122
|
#
|
|
128
123
|
# @note libdiscid >= 0.3.0 required. Older versions will always return nil.
|
|
129
124
|
# Not available on all platforms, see
|
|
130
|
-
# {
|
|
125
|
+
# {https://musicbrainz.org/doc/libdiscid#Feature_Matrix}.
|
|
131
126
|
#
|
|
132
127
|
# @return [String] MCN or `nil` if no ID was yet read.
|
|
133
128
|
def mcn
|
|
134
|
-
|
|
129
|
+
Lib.get_mcn @handle if @read
|
|
135
130
|
end
|
|
136
131
|
|
|
137
132
|
# Return a string representing CD Table Of Contents (TOC).
|
|
@@ -151,20 +146,20 @@ module DiscId
|
|
|
151
146
|
# could not get extracted from {Disc#submission_url}
|
|
152
147
|
# @return [String] The TOC string or `nil` if no ID was yet read.
|
|
153
148
|
def toc_string
|
|
154
|
-
return nil
|
|
149
|
+
return nil unless @read
|
|
150
|
+
|
|
155
151
|
result = Lib.get_toc_string @handle
|
|
156
|
-
|
|
152
|
+
unless result
|
|
157
153
|
# probably an old version of libdiscid (< 0.6.0)
|
|
158
154
|
# gather toc string from submission_url
|
|
159
|
-
match = /toc=([0-9+]+)/.match
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
end
|
|
155
|
+
match = /toc=([0-9+]+)/.match submission_url
|
|
156
|
+
|
|
157
|
+
raise "can't get toc string from submission url" unless match
|
|
158
|
+
|
|
159
|
+
result = match[1].tr('+', ' ')
|
|
165
160
|
end
|
|
166
161
|
|
|
167
|
-
|
|
162
|
+
result
|
|
168
163
|
end
|
|
169
164
|
|
|
170
165
|
# An URL for submitting the DiscID to MusicBrainz.
|
|
@@ -175,7 +170,7 @@ module DiscId
|
|
|
175
170
|
#
|
|
176
171
|
# @return [String] Submission URL
|
|
177
172
|
def submission_url
|
|
178
|
-
|
|
173
|
+
Lib.get_submission_url @handle if @read
|
|
179
174
|
end
|
|
180
175
|
|
|
181
176
|
# DiscID to String conversion. Same as calling the method {#id} but guaranteed
|
|
@@ -198,25 +193,23 @@ module DiscId
|
|
|
198
193
|
# @yieldreturn [nil]
|
|
199
194
|
# @return [Array<Track>] Array of {Track} objects.
|
|
200
195
|
def tracks(&block)
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
end
|
|
210
|
-
end
|
|
196
|
+
return unless @read
|
|
197
|
+
|
|
198
|
+
read_tracks if @tracks.nil?
|
|
199
|
+
|
|
200
|
+
return @tracks unless block
|
|
201
|
+
|
|
202
|
+
@tracks.each(&block)
|
|
203
|
+
nil
|
|
211
204
|
end
|
|
212
205
|
|
|
213
206
|
private
|
|
214
207
|
|
|
215
208
|
def read_tracks
|
|
216
|
-
track_number =
|
|
209
|
+
track_number = first_track_number - 1
|
|
217
210
|
@tracks = []
|
|
218
211
|
|
|
219
|
-
while track_number <
|
|
212
|
+
while track_number < last_track_number
|
|
220
213
|
track_number += 1
|
|
221
214
|
isrc = Lib.get_track_isrc(@handle, track_number)
|
|
222
215
|
offset = Lib.get_track_offset(@handle, track_number)
|
data/lib/discid/lib.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2013 Philipp Wolfer
|
|
1
|
+
# Copyright (C) 2013, 2025-2026 Philipp Wolfer
|
|
2
2
|
#
|
|
3
3
|
# This program is free software: you can redistribute it and/or modify
|
|
4
4
|
# it under the terms of the GNU Lesser General Public License as published by
|
|
@@ -13,9 +13,8 @@
|
|
|
13
13
|
# You should have received a copy of the GNU Lesser General Public License
|
|
14
14
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
15
15
|
|
|
16
|
-
require
|
|
16
|
+
require 'ffi'
|
|
17
17
|
|
|
18
|
-
#
|
|
19
18
|
module DiscId
|
|
20
19
|
|
|
21
20
|
# This module encapsulates the C interface for libdiscid using FFI.
|
|
@@ -32,16 +31,16 @@ module DiscId
|
|
|
32
31
|
attach_function :free, :discid_free, [:pointer], :void
|
|
33
32
|
|
|
34
33
|
begin
|
|
35
|
-
attach_function :read, :discid_read_sparse, [
|
|
34
|
+
attach_function :read, :discid_read_sparse, %i[pointer string uint], :int
|
|
36
35
|
rescue FFI::NotFoundError
|
|
37
|
-
attach_function :legacy_read, :discid_read, [
|
|
36
|
+
attach_function :legacy_read, :discid_read, %i[pointer string], :int
|
|
38
37
|
|
|
39
38
|
def self.read(handle, device, _features)
|
|
40
39
|
legacy_read(handle, device)
|
|
41
40
|
end
|
|
42
41
|
end
|
|
43
42
|
|
|
44
|
-
attach_function :put, :discid_put, [
|
|
43
|
+
attach_function :put, :discid_put, %i[pointer int int pointer], :int
|
|
45
44
|
|
|
46
45
|
attach_function :get_error_msg, :discid_get_error_msg, [:pointer], :string
|
|
47
46
|
|
|
@@ -59,15 +58,15 @@ module DiscId
|
|
|
59
58
|
|
|
60
59
|
attach_function :get_sectors, :discid_get_sectors, [:pointer], :int
|
|
61
60
|
|
|
62
|
-
attach_function :get_track_offset, :discid_get_track_offset, [
|
|
61
|
+
attach_function :get_track_offset, :discid_get_track_offset, %i[pointer int], :int
|
|
63
62
|
|
|
64
|
-
attach_function :get_track_length, :discid_get_track_length, [
|
|
63
|
+
attach_function :get_track_length, :discid_get_track_length, %i[pointer int], :int
|
|
65
64
|
|
|
66
65
|
begin
|
|
67
66
|
attach_function :get_toc_string, :discid_get_toc_string, [:pointer], :string
|
|
68
67
|
rescue FFI::NotFoundError
|
|
69
|
-
def self.get_toc_string
|
|
70
|
-
|
|
68
|
+
def self.get_toc_string(_handle)
|
|
69
|
+
nil
|
|
71
70
|
end
|
|
72
71
|
end
|
|
73
72
|
|
|
@@ -75,15 +74,15 @@ module DiscId
|
|
|
75
74
|
attach_function :get_mcn, :discid_get_mcn, [:pointer], :string
|
|
76
75
|
rescue FFI::NotFoundError
|
|
77
76
|
def self.get_mcn(_handle)
|
|
78
|
-
|
|
77
|
+
nil
|
|
79
78
|
end
|
|
80
79
|
end
|
|
81
80
|
|
|
82
81
|
begin
|
|
83
|
-
attach_function :get_track_isrc, :discid_get_track_isrc, [
|
|
82
|
+
attach_function :get_track_isrc, :discid_get_track_isrc, %i[pointer int], :string
|
|
84
83
|
rescue FFI::NotFoundError
|
|
85
84
|
def self.get_track_isrc(_handle, _track)
|
|
86
|
-
|
|
85
|
+
nil
|
|
87
86
|
end
|
|
88
87
|
end
|
|
89
88
|
|
|
@@ -94,19 +93,23 @@ module DiscId
|
|
|
94
93
|
begin
|
|
95
94
|
attach_function :has_feature, :discid_has_feature, [:feature], :int
|
|
96
95
|
rescue FFI::NotFoundError
|
|
96
|
+
# rubocop:disable Naming/PredicatePrefix
|
|
97
97
|
def self.has_feature(feature)
|
|
98
|
-
|
|
98
|
+
feature.to_sym == :read ? 1 : 0
|
|
99
99
|
end
|
|
100
|
+
# rubocop:enable Naming/PredicatePrefix
|
|
100
101
|
end
|
|
101
102
|
|
|
102
|
-
#attach_function :get_feature_list, :discid_get_feature_list, [:pointer], :void
|
|
103
|
+
# attach_function :get_feature_list, :discid_get_feature_list, [:pointer], :void
|
|
103
104
|
|
|
104
105
|
begin
|
|
105
106
|
attach_function :get_version_string, :discid_get_version_string, [], :string
|
|
106
107
|
rescue FFI::NotFoundError
|
|
108
|
+
# rubocop:disable Naming/AccessorMethodName
|
|
107
109
|
def self.get_version_string
|
|
108
|
-
|
|
110
|
+
'libdiscid < 0.4.0'
|
|
109
111
|
end
|
|
112
|
+
# rubocop:enable Naming/AccessorMethodName
|
|
110
113
|
end
|
|
111
114
|
|
|
112
115
|
def self.features_to_int(features)
|
|
@@ -114,20 +117,19 @@ module DiscId
|
|
|
114
117
|
features.each do |feature|
|
|
115
118
|
if feature.respond_to? :to_sym
|
|
116
119
|
feature = feature.to_sym
|
|
117
|
-
feature_flags =
|
|
120
|
+
feature_flags = add_feature_to_flags(feature_flags, feature)
|
|
118
121
|
end
|
|
119
122
|
end
|
|
120
123
|
|
|
121
|
-
|
|
124
|
+
feature_flags
|
|
122
125
|
end
|
|
123
126
|
|
|
124
|
-
private
|
|
125
|
-
|
|
126
127
|
def self.add_feature_to_flags(flags, feature)
|
|
127
128
|
flags |= self::Features[feature] if
|
|
128
|
-
self::Features.symbols.include?(feature)
|
|
129
|
-
|
|
130
|
-
return flags
|
|
129
|
+
self::Features.symbols.include?(feature) && has_feature(feature)
|
|
130
|
+
flags
|
|
131
131
|
end
|
|
132
|
+
|
|
133
|
+
private_class_method :add_feature_to_flags
|
|
132
134
|
end
|
|
133
135
|
end
|
data/lib/discid/track.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2008-2023 Philipp Wolfer
|
|
1
|
+
# Copyright (C) 2008-2023, 2025 Philipp Wolfer
|
|
2
2
|
#
|
|
3
3
|
# This program is free software: you can redistribute it and/or modify
|
|
4
4
|
# it under the terms of the GNU Lesser General Public License as published by
|
|
@@ -59,7 +59,7 @@ module DiscId
|
|
|
59
59
|
#
|
|
60
60
|
# @note libdiscid >= 0.3.0 required. Older versions will always return nil.
|
|
61
61
|
# Not available on all platforms, see
|
|
62
|
-
# {
|
|
62
|
+
# {https://musicbrainz.org/doc/libdiscid#Feature_Matrix}.
|
|
63
63
|
#
|
|
64
64
|
# @return [String]
|
|
65
65
|
attr_reader :isrc
|
|
@@ -108,8 +108,8 @@ module DiscId
|
|
|
108
108
|
# puts track.sectors # 16007
|
|
109
109
|
# puts track[:sectors] # 16007
|
|
110
110
|
def [](key)
|
|
111
|
-
if [
|
|
112
|
-
|
|
111
|
+
if %i[number sectors offset end_sector
|
|
112
|
+
seconds start_time end_time isrc].include?(key.to_sym)
|
|
113
113
|
method(key).call
|
|
114
114
|
end
|
|
115
115
|
end
|
|
@@ -119,17 +119,17 @@ module DiscId
|
|
|
119
119
|
# @return [Hash]
|
|
120
120
|
def to_h
|
|
121
121
|
{
|
|
122
|
-
:
|
|
123
|
-
:
|
|
124
|
-
:
|
|
125
|
-
:
|
|
126
|
-
:
|
|
127
|
-
:
|
|
128
|
-
:
|
|
129
|
-
:
|
|
122
|
+
number: number,
|
|
123
|
+
sectors: sectors,
|
|
124
|
+
offset: offset,
|
|
125
|
+
end_sector: end_sector,
|
|
126
|
+
seconds: seconds,
|
|
127
|
+
start_time: start_time,
|
|
128
|
+
end_time: end_time,
|
|
129
|
+
isrc: isrc
|
|
130
130
|
}
|
|
131
131
|
end
|
|
132
132
|
|
|
133
|
-
|
|
133
|
+
alias to_hash to_h
|
|
134
134
|
end
|
|
135
135
|
end
|
data/lib/discid/version.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2013-2023 Philipp Wolfer
|
|
1
|
+
# Copyright (C) 2013-2023, 2025 Philipp Wolfer
|
|
2
2
|
#
|
|
3
3
|
# This program is free software: you can redistribute it and/or modify
|
|
4
4
|
# it under the terms of the GNU Lesser General Public License as published by
|
|
@@ -16,5 +16,5 @@
|
|
|
16
16
|
#
|
|
17
17
|
module DiscId
|
|
18
18
|
# The version of ruby-discid.
|
|
19
|
-
VERSION =
|
|
19
|
+
VERSION = '1.7.0'.freeze
|
|
20
20
|
end
|
data/lib/discid.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2013-2017, 2019 Philipp Wolfer
|
|
1
|
+
# Copyright (C) 2013-2017, 2019, 2025-2026 Philipp Wolfer
|
|
2
2
|
#
|
|
3
3
|
# This program is free software: you can redistribute it and/or modify
|
|
4
4
|
# it under the terms of the GNU Lesser General Public License as published by
|
|
@@ -28,9 +28,9 @@ require 'discid/version'
|
|
|
28
28
|
#
|
|
29
29
|
# Depending on the version of libdiscid and the operating system used
|
|
30
30
|
# additional features like reading the MCN or ISRCs from the disc
|
|
31
|
-
# might be available. You can check for supported features with {
|
|
31
|
+
# might be available. You can check for supported features with {feature?}.
|
|
32
32
|
#
|
|
33
|
-
# @see
|
|
33
|
+
# @see https://musicbrainz.org/doc/libdiscid#Feature_Matrix
|
|
34
34
|
#
|
|
35
35
|
# @example Read the TOC, MCN and ISRCs
|
|
36
36
|
# require 'discid'
|
|
@@ -63,7 +63,7 @@ require 'discid/version'
|
|
|
63
63
|
#
|
|
64
64
|
# @example Check for supported MCN feature
|
|
65
65
|
# disc = DiscId.read(nil, :mcn)
|
|
66
|
-
# puts "MCN: #{disc.mcn}" if DiscId.
|
|
66
|
+
# puts "MCN: #{disc.mcn}" if DiscId.feature?(:mcn)
|
|
67
67
|
module DiscId
|
|
68
68
|
|
|
69
69
|
# Read the disc in the given CD-ROM/DVD-ROM drive extracting only the
|
|
@@ -85,7 +85,7 @@ module DiscId
|
|
|
85
85
|
#
|
|
86
86
|
# @note libdiscid >= 0.5.0 is required for the feature selection to work.
|
|
87
87
|
# Older versions will allways read MCN and ISRCs when supported. See
|
|
88
|
-
# {
|
|
88
|
+
# {https://musicbrainz.org/doc/libdiscid#Feature_Matrix} for a list of
|
|
89
89
|
# supported features by version and platform.
|
|
90
90
|
#
|
|
91
91
|
# @raise [TypeError] `device` can not be converted to a String.
|
|
@@ -99,7 +99,7 @@ module DiscId
|
|
|
99
99
|
def self.read(device = nil, *features)
|
|
100
100
|
disc = Disc.new
|
|
101
101
|
disc.read device, *features
|
|
102
|
-
|
|
102
|
+
disc
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
# Provides the TOC of a known CD.
|
|
@@ -117,21 +117,20 @@ module DiscId
|
|
|
117
117
|
def self.put(first_track, sectors, offsets)
|
|
118
118
|
disc = Disc.new
|
|
119
119
|
disc.put first_track, sectors, offsets
|
|
120
|
-
|
|
120
|
+
disc
|
|
121
121
|
end
|
|
122
122
|
|
|
123
123
|
# Parses a TOC string and returns a [Disc] instance for it.
|
|
124
124
|
#
|
|
125
125
|
# This function can be used if you already have a TOC string like e.g.
|
|
126
|
-
# `1
|
|
126
|
+
# `1 4 78615 150 20971 36350 54056`.
|
|
127
127
|
#
|
|
128
128
|
# @raise [DiscError] The TOC string was invalid and could not be parsed.
|
|
129
|
-
# @param toc [String] A TOC string in the format `1
|
|
129
|
+
# @param toc [String] A TOC string in the format `1 4 78615 150 20971 36350 54056`.
|
|
130
130
|
# @return [Disc]
|
|
131
131
|
def self.parse(toc)
|
|
132
|
-
if toc.nil? || toc.empty?
|
|
133
|
-
|
|
134
|
-
end
|
|
132
|
+
raise DiscError, "Invalid TOC #{toc.inspect}" if toc.nil? || toc.empty?
|
|
133
|
+
|
|
135
134
|
begin
|
|
136
135
|
parts = toc.split(' ')
|
|
137
136
|
first_track = Integer(parts[0])
|
|
@@ -140,7 +139,7 @@ module DiscId
|
|
|
140
139
|
rescue ArgumentError, TypeError => e
|
|
141
140
|
raise DiscError, e
|
|
142
141
|
end
|
|
143
|
-
|
|
142
|
+
put(first_track, sectors, offsets)
|
|
144
143
|
end
|
|
145
144
|
|
|
146
145
|
# Return the name of the default disc drive for this operating system.
|
|
@@ -157,13 +156,24 @@ module DiscId
|
|
|
157
156
|
# @note libdiscid >= 0.5.0 required. Older versions will return `true`
|
|
158
157
|
# for `:read` and `false` for anything else.
|
|
159
158
|
#
|
|
159
|
+
# @note Before version 1.7 this method was called `has_feature?`, which is
|
|
160
|
+
# deprecated but still available as an alias.
|
|
161
|
+
#
|
|
162
|
+
# @since 1.7
|
|
163
|
+
#
|
|
160
164
|
# @param feature [:read, :mcn, :isrc]
|
|
161
165
|
# @return [Boolean] True if the feature is implemented and false if not.
|
|
162
|
-
def self.
|
|
166
|
+
def self.feature?(feature)
|
|
163
167
|
feature = feature.to_sym if feature.respond_to? :to_sym
|
|
164
|
-
|
|
168
|
+
feature_list.include? feature
|
|
165
169
|
end
|
|
166
170
|
|
|
171
|
+
# Provide has_feature? for backward compatibility
|
|
172
|
+
#
|
|
173
|
+
# @deprecated Use {#feature?} instead.
|
|
174
|
+
# @!scope module
|
|
175
|
+
singleton_class.alias_method :has_feature?, :feature?
|
|
176
|
+
|
|
167
177
|
# A list of features supported by the current platform.
|
|
168
178
|
#
|
|
169
179
|
# Currently the following features are available:
|
|
@@ -176,7 +186,7 @@ module DiscId
|
|
|
176
186
|
#
|
|
177
187
|
# @return [Array<Symbol>]
|
|
178
188
|
def self.feature_list
|
|
179
|
-
|
|
189
|
+
Lib::Features.symbols.select { |f| Lib.has_feature(f) == 1 }
|
|
180
190
|
end
|
|
181
191
|
|
|
182
192
|
# Converts sectors to seconds.
|
|
@@ -187,7 +197,7 @@ module DiscId
|
|
|
187
197
|
# @param sectors [Integer] Number of sectors
|
|
188
198
|
# @return [Integer] The seconds
|
|
189
199
|
def self.sectors_to_seconds(sectors)
|
|
190
|
-
|
|
200
|
+
(sectors.to_f / 75).truncate
|
|
191
201
|
end
|
|
192
202
|
|
|
193
203
|
# The libdiscid version.
|
data/test/helper.rb
CHANGED
|
@@ -17,12 +17,14 @@ begin
|
|
|
17
17
|
require 'simplecov'
|
|
18
18
|
require 'simplecov_small_badge'
|
|
19
19
|
|
|
20
|
-
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
|
|
21
|
+
[
|
|
22
|
+
SimpleCov::Formatter::HTMLFormatter,
|
|
23
|
+
SimpleCovSmallBadge::Formatter
|
|
24
|
+
]
|
|
25
|
+
)
|
|
24
26
|
SimpleCov.start do
|
|
25
|
-
add_filter
|
|
27
|
+
add_filter '/test/'
|
|
26
28
|
end
|
|
27
29
|
rescue LoadError
|
|
28
30
|
puts 'WARNING: simplecov not available, no code coverage reported.'
|
data/test/test_disc.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2013-2014 Philipp Wolfer
|
|
1
|
+
# Copyright (C) 2013-2014, 2025 Philipp Wolfer
|
|
2
2
|
#
|
|
3
3
|
# This program is free software: you can redistribute it and/or modify
|
|
4
4
|
# it under the terms of the GNU Lesser General Public License as published by
|
|
@@ -24,15 +24,12 @@ class TestDisc < Test::Unit::TestCase
|
|
|
24
24
|
@fiction_disc_id = 'Wn8eRBtfLDfM0qjYPdxrz.Zjs_U-'
|
|
25
25
|
@fiction_first_track = 1
|
|
26
26
|
@fiction_last_track = 10
|
|
27
|
-
@fiction_sectors =
|
|
27
|
+
@fiction_sectors = 206_535
|
|
28
28
|
@fiction_seconds = 2753
|
|
29
|
-
@fiction_offsets = [150,
|
|
30
|
-
|
|
31
|
-
@fiction_lengths = [
|
|
32
|
-
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def teardown
|
|
29
|
+
@fiction_offsets = [150, 18_901, 39_738, 59_557, 79_152, 100_126,
|
|
30
|
+
124_833, 147_278, 166_336, 182_560]
|
|
31
|
+
@fiction_lengths = [18_751, 20_837, 19_819, 19_595, 20_974,
|
|
32
|
+
24_707, 22_445, 19_058, 16_224, 23_975]
|
|
36
33
|
end
|
|
37
34
|
|
|
38
35
|
def test_empty_disc
|
|
@@ -54,7 +51,7 @@ class TestDisc < Test::Unit::TestCase
|
|
|
54
51
|
# Test calculation of the disc id if the TOC information
|
|
55
52
|
# gets set by the put method.
|
|
56
53
|
# All attributes should be nil after a failure, even if there was a
|
|
57
|
-
#
|
|
54
|
+
# successful put before.
|
|
58
55
|
def test_put
|
|
59
56
|
disc = DiscId::Disc.new
|
|
60
57
|
|
|
@@ -70,7 +67,7 @@ class TestDisc < Test::Unit::TestCase
|
|
|
70
67
|
assert_equal nil, disc.seconds
|
|
71
68
|
assert_equal nil, disc.tracks
|
|
72
69
|
|
|
73
|
-
# Second
|
|
70
|
+
# Second successful put
|
|
74
71
|
assert_nothing_raised do
|
|
75
72
|
disc = DiscId.put(@fiction_first_track, @fiction_sectors,
|
|
76
73
|
@fiction_offsets)
|
|
@@ -81,8 +78,8 @@ class TestDisc < Test::Unit::TestCase
|
|
|
81
78
|
assert_equal @fiction_last_track, disc.last_track_number
|
|
82
79
|
assert_equal @fiction_sectors, disc.sectors
|
|
83
80
|
assert_equal @fiction_seconds, disc.seconds
|
|
84
|
-
assert_equal
|
|
85
|
-
assert_equal
|
|
81
|
+
assert_equal(@fiction_offsets, disc.tracks.map { |t| t.offset })
|
|
82
|
+
assert_equal(@fiction_lengths, disc.tracks.map { |t| t.sectors })
|
|
86
83
|
end
|
|
87
84
|
|
|
88
85
|
def test_toc_string
|
data/test/test_discid.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2013-2014 Philipp Wolfer
|
|
1
|
+
# Copyright (C) 2013-2014, 2025 Philipp Wolfer
|
|
2
2
|
#
|
|
3
3
|
# This program is free software: you can redistribute it and/or modify
|
|
4
4
|
# it under the terms of the GNU Lesser General Public License as published by
|
|
@@ -22,8 +22,7 @@ class NotAString
|
|
|
22
22
|
|
|
23
23
|
private
|
|
24
24
|
|
|
25
|
-
def to_s
|
|
26
|
-
end
|
|
25
|
+
def to_s; end
|
|
27
26
|
|
|
28
27
|
end
|
|
29
28
|
|
|
@@ -36,20 +35,17 @@ class TestDiscId < Test::Unit::TestCase
|
|
|
36
35
|
@fiction_last_track = 10
|
|
37
36
|
@fiction_sectors = 206535
|
|
38
37
|
@fiction_seconds = 2753
|
|
39
|
-
@fiction_offsets = [150,
|
|
40
|
-
|
|
41
|
-
@fiction_lengths = [
|
|
42
|
-
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def teardown
|
|
38
|
+
@fiction_offsets = [150, 18_901, 39_738, 59_557, 79_152, 100_126,
|
|
39
|
+
124_833, 147_278, 166_336, 182_560]
|
|
40
|
+
@fiction_lengths = [18_751, 20_837, 19_819, 19_595, 20_974,
|
|
41
|
+
24_707, 22_445, 19_058, 16_224, 23_975]
|
|
46
42
|
end
|
|
47
43
|
|
|
48
44
|
# Test reading the disc id from a device.
|
|
49
45
|
# We would need some kind of small test data to do this.
|
|
50
|
-
#def test_read
|
|
51
|
-
#
|
|
52
|
-
#end
|
|
46
|
+
# def test_read
|
|
47
|
+
# assert false, "Not implemented yet"
|
|
48
|
+
# end
|
|
53
49
|
|
|
54
50
|
# Test how read reacts on different arguments.
|
|
55
51
|
# Those reads should all fail, but they must never cause a segmentation fault.
|
|
@@ -61,9 +57,9 @@ class TestDiscId < Test::Unit::TestCase
|
|
|
61
57
|
|
|
62
58
|
def test_put_first_track_not_one
|
|
63
59
|
disc = DiscId.put(3, @fiction_sectors,
|
|
64
|
-
[150,
|
|
65
|
-
|
|
66
|
-
assert_equal
|
|
60
|
+
[150, 18_901, 39_738, 59_557, 79_152, 100_126,
|
|
61
|
+
124_833, 147_278, 166_336, 182_560])
|
|
62
|
+
assert_equal 'ByBKvJM1hBL7XtvsPyYtIjlX0Bw-', disc.id
|
|
67
63
|
assert_equal 3, disc.first_track_number
|
|
68
64
|
assert_equal 12, disc.last_track_number
|
|
69
65
|
assert_equal 10, disc.tracks.size
|
|
@@ -71,7 +67,7 @@ class TestDiscId < Test::Unit::TestCase
|
|
|
71
67
|
|
|
72
68
|
def test_put_invalid_track_count
|
|
73
69
|
assert_raise(DiscId::DiscError) do
|
|
74
|
-
DiscId.put(1, @fiction_sectors, Array.new(101) {|i| i + 150 })
|
|
70
|
+
DiscId.put(1, @fiction_sectors, Array.new(101) { |i| i + 150 })
|
|
75
71
|
end
|
|
76
72
|
end
|
|
77
73
|
|
|
@@ -91,7 +87,7 @@ class TestDiscId < Test::Unit::TestCase
|
|
|
91
87
|
|
|
92
88
|
assert_equal @fiction_offsets[number], track.offset
|
|
93
89
|
assert_equal @fiction_lengths[number], track.sectors
|
|
94
|
-
assert_equal @fiction_offsets[number]+ @fiction_lengths[number],
|
|
90
|
+
assert_equal @fiction_offsets[number] + @fiction_lengths[number],
|
|
95
91
|
track.end_sector
|
|
96
92
|
|
|
97
93
|
assert_equal(DiscId.sectors_to_seconds(@fiction_offsets[number]),
|
|
@@ -99,8 +95,8 @@ class TestDiscId < Test::Unit::TestCase
|
|
|
99
95
|
assert_equal(DiscId.sectors_to_seconds(@fiction_lengths[number]),
|
|
100
96
|
track.seconds)
|
|
101
97
|
assert_equal(DiscId.sectors_to_seconds(
|
|
102
|
-
|
|
103
|
-
track.end_time)
|
|
98
|
+
@fiction_offsets[number] + @fiction_lengths[number]
|
|
99
|
+
), track.end_time)
|
|
104
100
|
|
|
105
101
|
number += 1
|
|
106
102
|
end
|
|
@@ -147,17 +143,17 @@ class TestDiscId < Test::Unit::TestCase
|
|
|
147
143
|
end
|
|
148
144
|
|
|
149
145
|
def test_parse_invalid_empty
|
|
150
|
-
assert_raise(DiscId::DiscError) { DiscId.parse(
|
|
146
|
+
assert_raise(DiscId::DiscError) { DiscId.parse('') }
|
|
151
147
|
assert_raise(DiscId::DiscError) { DiscId.parse(nil) }
|
|
152
148
|
end
|
|
153
149
|
|
|
154
150
|
def test_parse_invalid_nan
|
|
155
|
-
assert_raise(DiscId::DiscError) { DiscId.parse(
|
|
151
|
+
assert_raise(DiscId::DiscError) { DiscId.parse('1 2 242457 150 a') }
|
|
156
152
|
end
|
|
157
153
|
|
|
158
154
|
def test_parse_invalid_not_enough_elements
|
|
159
|
-
assert_raise(DiscId::DiscError) { DiscId.parse(
|
|
160
|
-
assert_raise(DiscId::DiscError) { DiscId.parse(
|
|
155
|
+
assert_raise(DiscId::DiscError) { DiscId.parse('1 2 242457') }
|
|
156
|
+
assert_raise(DiscId::DiscError) { DiscId.parse('1 242457') }
|
|
161
157
|
end
|
|
162
158
|
|
|
163
159
|
# Test the conversion from sectors to seconds
|
|
@@ -166,35 +162,37 @@ class TestDiscId < Test::Unit::TestCase
|
|
|
166
162
|
assert_equal @fiction_seconds,
|
|
167
163
|
DiscId.sectors_to_seconds(@fiction_sectors)
|
|
168
164
|
assert_equal 1, DiscId.sectors_to_seconds(75)
|
|
169
|
-
assert_equal 1, DiscId.sectors_to_seconds(75+74)
|
|
170
|
-
assert_equal 2, DiscId.sectors_to_seconds(75+75)
|
|
165
|
+
assert_equal 1, DiscId.sectors_to_seconds(75 + 74)
|
|
166
|
+
assert_equal 2, DiscId.sectors_to_seconds(75 + 75)
|
|
171
167
|
end
|
|
172
168
|
|
|
173
169
|
def test_has_feature
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
170
|
+
%i[has_feature? feature?].each do |f|
|
|
171
|
+
assert(DiscId.send(f, :read),
|
|
172
|
+
'Feature :read should be supported')
|
|
173
|
+
assert(DiscId.send(f, 'read'),
|
|
174
|
+
"Feature 'read' should be supported")
|
|
175
|
+
assert(!DiscId.send(f, :notafeature),
|
|
176
|
+
'Feature :notafeature should not be supported')
|
|
177
|
+
assert(!DiscId.send(f, 'notafeature'),
|
|
178
|
+
"Feature 'notafeature' should not be supported")
|
|
179
|
+
end
|
|
182
180
|
end
|
|
183
181
|
|
|
184
182
|
def test_feature_list_must_contain_read
|
|
185
183
|
assert(DiscId.feature_list.include?(:read),
|
|
186
|
-
|
|
184
|
+
'Feature :read should be supported')
|
|
187
185
|
end
|
|
188
186
|
|
|
189
187
|
def test_libdiscid_version_should_start_with_libdiscid
|
|
190
188
|
version = DiscId::LIBDISCID_VERSION
|
|
191
|
-
assert version.
|
|
192
|
-
assert version.start_with?(
|
|
189
|
+
assert version.is_a?(String)
|
|
190
|
+
assert version.start_with?('libdiscid')
|
|
193
191
|
end
|
|
194
192
|
|
|
195
193
|
def test_default_device_is_a_string
|
|
196
194
|
device = DiscId.default_device
|
|
197
|
-
assert device.
|
|
195
|
+
assert device.is_a?(String)
|
|
198
196
|
end
|
|
199
197
|
|
|
200
198
|
end
|
data/test/test_lib.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2013-2014 Philipp Wolfer
|
|
1
|
+
# Copyright (C) 2013-2014, 2025 Philipp Wolfer
|
|
2
2
|
#
|
|
3
3
|
# This program is free software: you can redistribute it and/or modify
|
|
4
4
|
# it under the terms of the GNU Lesser General Public License as published by
|
|
@@ -31,7 +31,7 @@ class TestTrack < Test::Unit::TestCase
|
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def test_features_to_int_ignores_unknown
|
|
34
|
-
assert_equal 1, DiscId::Lib.features_to_int([
|
|
34
|
+
assert_equal 1, DiscId::Lib.features_to_int(%i[read fake])
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def test_has_feature
|
data/test/test_track.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2013-2014 Philipp Wolfer
|
|
1
|
+
# Copyright (C) 2013-2014, 2025 Philipp Wolfer
|
|
2
2
|
#
|
|
3
3
|
# This program is free software: you can redistribute it and/or modify
|
|
4
4
|
# it under the terms of the GNU Lesser General Public License as published by
|
|
@@ -23,8 +23,8 @@ class TestTrack < Test::Unit::TestCase
|
|
|
23
23
|
def setup
|
|
24
24
|
@number = 3
|
|
25
25
|
@offset = 1035
|
|
26
|
-
@length =
|
|
27
|
-
@isrc =
|
|
26
|
+
@length = 23_643
|
|
27
|
+
@isrc = 'US4E40731510'
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def test_init_track_info
|
|
@@ -44,7 +44,7 @@ class TestTrack < Test::Unit::TestCase
|
|
|
44
44
|
def test_to_hash
|
|
45
45
|
track = DiscId::Track.new @number, @offset, @length, @isrc
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
%i[to_h to_hash].each do |f|
|
|
48
48
|
hash = track.send(f)
|
|
49
49
|
|
|
50
50
|
assert_equal track.number, hash[:number]
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: discid
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Philipp Wolfer
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: ffi
|
|
@@ -30,14 +29,20 @@ dependencies:
|
|
|
30
29
|
requirements:
|
|
31
30
|
- - ">="
|
|
32
31
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
32
|
+
version: '12.3'
|
|
33
|
+
- - "<"
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: '14.0'
|
|
34
36
|
type: :development
|
|
35
37
|
prerelease: false
|
|
36
38
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
39
|
requirements:
|
|
38
40
|
- - ">="
|
|
39
41
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
42
|
+
version: '12.3'
|
|
43
|
+
- - "<"
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '14.0'
|
|
41
46
|
- !ruby/object:Gem::Dependency
|
|
42
47
|
name: bundler
|
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -45,6 +50,9 @@ dependencies:
|
|
|
45
50
|
- - ">="
|
|
46
51
|
- !ruby/object:Gem::Version
|
|
47
52
|
version: '1.3'
|
|
53
|
+
- - "<"
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: '3.0'
|
|
48
56
|
type: :development
|
|
49
57
|
prerelease: false
|
|
50
58
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -52,76 +60,79 @@ dependencies:
|
|
|
52
60
|
- - ">="
|
|
53
61
|
- !ruby/object:Gem::Version
|
|
54
62
|
version: '1.3'
|
|
63
|
+
- - "<"
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: '3.0'
|
|
55
66
|
- !ruby/object:Gem::Dependency
|
|
56
67
|
name: yard
|
|
57
68
|
requirement: !ruby/object:Gem::Requirement
|
|
58
69
|
requirements:
|
|
59
|
-
- - "
|
|
70
|
+
- - "~>"
|
|
60
71
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '0'
|
|
72
|
+
version: '0.9'
|
|
62
73
|
type: :development
|
|
63
74
|
prerelease: false
|
|
64
75
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
76
|
requirements:
|
|
66
|
-
- - "
|
|
77
|
+
- - "~>"
|
|
67
78
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '0'
|
|
79
|
+
version: '0.9'
|
|
69
80
|
- !ruby/object:Gem::Dependency
|
|
70
81
|
name: redcarpet
|
|
71
82
|
requirement: !ruby/object:Gem::Requirement
|
|
72
83
|
requirements:
|
|
73
|
-
- - "
|
|
84
|
+
- - "~>"
|
|
74
85
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
86
|
+
version: '3.6'
|
|
76
87
|
type: :development
|
|
77
88
|
prerelease: false
|
|
78
89
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
90
|
requirements:
|
|
80
|
-
- - "
|
|
91
|
+
- - "~>"
|
|
81
92
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '
|
|
93
|
+
version: '3.6'
|
|
83
94
|
- !ruby/object:Gem::Dependency
|
|
84
95
|
name: test-unit
|
|
85
96
|
requirement: !ruby/object:Gem::Requirement
|
|
86
97
|
requirements:
|
|
87
|
-
- - "
|
|
98
|
+
- - "~>"
|
|
88
99
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '
|
|
100
|
+
version: '3.6'
|
|
90
101
|
type: :development
|
|
91
102
|
prerelease: false
|
|
92
103
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
104
|
requirements:
|
|
94
|
-
- - "
|
|
105
|
+
- - "~>"
|
|
95
106
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '
|
|
107
|
+
version: '3.6'
|
|
97
108
|
- !ruby/object:Gem::Dependency
|
|
98
109
|
name: simplecov
|
|
99
110
|
requirement: !ruby/object:Gem::Requirement
|
|
100
111
|
requirements:
|
|
101
|
-
- - "
|
|
112
|
+
- - "~>"
|
|
102
113
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: '0'
|
|
114
|
+
version: '0.22'
|
|
104
115
|
type: :development
|
|
105
116
|
prerelease: false
|
|
106
117
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
118
|
requirements:
|
|
108
|
-
- - "
|
|
119
|
+
- - "~>"
|
|
109
120
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: '0'
|
|
121
|
+
version: '0.22'
|
|
111
122
|
- !ruby/object:Gem::Dependency
|
|
112
123
|
name: simplecov-small-badge
|
|
113
124
|
requirement: !ruby/object:Gem::Requirement
|
|
114
125
|
requirements:
|
|
115
|
-
- - "
|
|
126
|
+
- - "~>"
|
|
116
127
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: '0'
|
|
128
|
+
version: '0.2'
|
|
118
129
|
type: :development
|
|
119
130
|
prerelease: false
|
|
120
131
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
132
|
requirements:
|
|
122
|
-
- - "
|
|
133
|
+
- - "~>"
|
|
123
134
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: '0'
|
|
135
|
+
version: '0.2'
|
|
125
136
|
description: ruby-discid provides Ruby bindings for the MusicBrainz DiscID library
|
|
126
137
|
libdiscid. It allows calculating DiscIDs (MusicBrainz and freedb) for Audio CDs.
|
|
127
138
|
Additionally the library can extract the MCN/UPC/EAN and the ISRCs from disc.
|
|
@@ -153,9 +164,9 @@ files:
|
|
|
153
164
|
- test/test_track.rb
|
|
154
165
|
homepage: https://git.sr.ht/~phw/ruby-discid
|
|
155
166
|
licenses:
|
|
156
|
-
- LGPL-3.0
|
|
167
|
+
- LGPL-3.0-or-later
|
|
157
168
|
metadata: {}
|
|
158
|
-
post_install_message: Please make sure you have libdiscid (
|
|
169
|
+
post_install_message: Please make sure you have libdiscid (https://musicbrainz.org/doc/libdiscid)
|
|
159
170
|
installed.
|
|
160
171
|
rdoc_options: []
|
|
161
172
|
require_paths:
|
|
@@ -172,8 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
172
183
|
version: 1.3.6
|
|
173
184
|
requirements:
|
|
174
185
|
- libdiscid >= 0.1.0
|
|
175
|
-
rubygems_version: 3.
|
|
176
|
-
signing_key:
|
|
186
|
+
rubygems_version: 3.6.9
|
|
177
187
|
specification_version: 4
|
|
178
188
|
summary: Ruby bindings for libdiscid
|
|
179
189
|
test_files:
|