music_ids 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d75caff64b4e4891c3f7ec2f74cd69565326ad32
4
- data.tar.gz: ce0f8a0238c334c6f9fae24e73d2a4e56c0047d9
3
+ metadata.gz: 0dcfa17ed18001f410a21d829f1b76e908d4434e
4
+ data.tar.gz: cc4b1fb8380914370cab6d9de1b1748f70ee4299
5
5
  SHA512:
6
- metadata.gz: 8c011793f6cc32c44a74add1a360e30c6b1c44791c145500ac1ac75b154a7d0dfed11e852d118035f55a564d6813ee9ad9c22a071da9c7bcf41998d03fa27f30
7
- data.tar.gz: 5ba4a46d7e81136e56299c0f6e1247735f133108527587305d55c8f492dbbb39e09e443a197e1e819001f775bba22500cef8ddadded324ca30c2bb8228cba4fd
6
+ metadata.gz: e1a729e07cea652ccacf911a0712b6b2a5c1696661ada9c65ebff2150edda6ab4a4bd461cfc9065e32f03bac7681f5ab968c72e206211c3095d471e1314e3e9d
7
+ data.tar.gz: eafd21cf4c04b24c2fd9980343cc6d15bfbd9962836a1ebaa2560c07d6d393bbf8e8850cb87f14bf2c972ada9013e9d5fe981037033e7ee147aa43dec6de2403
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # MusicIds
2
2
 
3
+ [![Build Status](https://travis-ci.org/tape-tv/music_ids.svg)](https://travis-ci.org/tape-tv/music_ids)[![Code Climate](https://codeclimate.com/github/tape-tv/music_ids/badges/gpa.svg)](https://codeclimate.com/github/tape-tv/music_ids)[![Test Coverage](https://codeclimate.com/github/tape-tv/music_ids/badges/coverage.svg)](https://codeclimate.com/github/tape-tv/music_ids/coverage)[![Gem Version](https://badge.fury.io/rb/music_ids.svg)](http://badge.fury.io/rb/music_ids) [RDoc](http://www.rubydoc.info/gems/music_ids)
4
+
3
5
  `music_ids` contains classes that represent some of the main ID formats in use in the music industry for identifying individual pieces of recorded music.
4
6
 
5
7
  There are often several ways that these IDs can be written, so the classes provide standard APIs to parse and normalise ID strings, as well as to break them into their components.
@@ -0,0 +1,144 @@
1
+ module MusicIds
2
+ # The GRid class represents a Global Release Identifier, and
3
+ # provides simple methods to parse and re-present them.
4
+ #
5
+ # == What is a GRid?
6
+ # GRid's are unique identifiers for Releases of recorded music, as distinct
7
+ # from different Products (See the GRid Handbook for more details). They're
8
+ # often used as key identifiers in the delivery and reporting of digital
9
+ # music products.
10
+ #
11
+ # You can get more details from
12
+ # https://en.wikipedia.org/wiki/Global_Release_Identifier and
13
+ # http://www.ifpi.org/grid.php
14
+ #
15
+ # == Well-formedness and validity
16
+ # GRid's are supposed to be able to be looked up in a global database, so we
17
+ # need to draw a distinction between *valid* GRid's, which are GRid's we have
18
+ # looked up and verified in that database, and well-formed GRid's, which are
19
+ # just strings that match the requirements above.
20
+ #
21
+ # Checking or enforcing validity is beyond the scope of this class.
22
+ # Well-formedness, on the other hand, is easy to check and enforce.
23
+ #
24
+ # While you don't want to be emitting badly-formed GRid's, if you handle
25
+ # GRid's from elsewhere you may well run across bad metadata that you need to
26
+ # preserve, but probably want to be aware of the fact that it's bad.
27
+ #
28
+ # To help with that there are two parsing modes, strict (the default), and
29
+ # relaxed.
30
+ #
31
+ # In strict parsing mode, <tt>GRid.parse</tt> will raise an error if passed a
32
+ # badly-formed GRid string. In relaxed mode, it will return an <tt>GRid</tt>
33
+ # instance that will return <tt>false</tt> from <tt>#ok?</tt> and will return
34
+ # nil from all the component methods like <tt>#issuer</tt>
35
+ class GRid
36
+ # See http://www.ifpi.org/downloads/GRid_Standard_v2_1.pdf §5
37
+ WELL_FORMED_INPUT = /\AA1-?[A-Z0-9]{5}-?[A-Z0-9]{10}-?[A-Z0-9]\Z/
38
+
39
+ class << self
40
+ # Parse a GRid string into a GRid instance
41
+ #
42
+ # @param input [String] The input GRid string to parse
43
+ # @param opts [Hash] Parsing options
44
+ # @option opts [true, false] :relaxed (false) Whether to parse in relaxed mode
45
+ # @return [GRid] the grid instance
46
+ def parse(input, opts = {})
47
+ input = input.to_s.upcase
48
+ opts[:relaxed] ? parse_relaxed(input) : parse_strict(input)
49
+ end
50
+
51
+ private
52
+
53
+ def parse_strict(input)
54
+ if WELL_FORMED_INPUT.match(input)
55
+ new(input.gsub('-', ''))
56
+ else
57
+ raise ArgumentError, "'#{input}' is not the right length to be a 12- or 15-character ISRC"
58
+ end
59
+ end
60
+
61
+ def parse_relaxed(input)
62
+ if WELL_FORMED_INPUT.match(input)
63
+ new(input.gsub('-', ''))
64
+ else
65
+ new(input, ok: false)
66
+ end
67
+ end
68
+ end
69
+
70
+ # @api private
71
+ # @param grid_string [String] The GRid string
72
+ # @param opts [Hash]
73
+ # @option opts [true, false] :ok (true) Whether the GRid is well-formed or not
74
+ def initialize(grid_string, opts = {ok: true})
75
+ @grid_string = grid_string.dup.freeze
76
+ @ok = opts[:ok] ? true : false
77
+ end
78
+
79
+ # Is this a well-formed GRid?
80
+ # @return [true,false]
81
+ def ok?
82
+ @ok
83
+ end
84
+
85
+ # Return the GRid's two-letter scheme identifier
86
+ # @return [String]
87
+ def scheme
88
+ return unless ok?
89
+ @scheme ||= @grid_string[0,2].freeze
90
+ end
91
+
92
+ # Return the GRid's 5-character issuer code
93
+ # @return [String]
94
+ def issuer
95
+ return unless ok?
96
+ @issuer ||= @grid_string[2,5].freeze
97
+ end
98
+
99
+ # Return the GRid's 10-character release number.
100
+ # @return [String]
101
+ def release
102
+ return unless ok?
103
+ @release ||= @grid_string[7,10].freeze
104
+ end
105
+
106
+ # Return the GRid's check character.
107
+ # @return [String]
108
+ def check
109
+ return unless ok?
110
+ @check ||= @grid_string[17,1].freeze
111
+ end
112
+
113
+ # return the GRid as a normalised 18-character string
114
+ # @reuturn [String]
115
+ def to_s
116
+ @grid_string.dup
117
+ end
118
+
119
+ def to_grid
120
+ self
121
+ end
122
+
123
+ def ==(other)
124
+ to_s == other.to_s
125
+ end
126
+
127
+ # Returns the GRid as a string, either the 18-character normalised string
128
+ # (:data) or the 21-character display string (:full). Note that a
129
+ # badly-formed GRid will simply return the original string whichever format
130
+ # you ask for.
131
+ # @param format [:data, :full] the output format to use
132
+ # @return [String]
133
+ def as(format)
134
+ case format
135
+ when :data
136
+ to_s
137
+ when :full
138
+ ok? ? "#{scheme}-#{issuer}-#{release}-#{check}" : to_s
139
+ else
140
+ raise ArgumentError, "format must be one of [:data, :full], but it was #{format.inspect}"
141
+ end
142
+ end
143
+ end
144
+ end
@@ -139,7 +139,9 @@ module MusicIds
139
139
  end
140
140
 
141
141
  # Returns the ISRC as a string, either the 12-character normalised string
142
- # (:data) or the 15-character display string (:full). Note that a badly-formed ISRC will simply return the original string whichever format you ask for
142
+ # (:data) or the 15-character display string (:full). Note that a
143
+ # badly-formed ISRC will simply return the original string whichever format
144
+ # you ask for.
143
145
  # @param format [:data, :full] the output format to use
144
146
  # @return [String]
145
147
  def as(format)
@@ -1,3 +1,3 @@
1
1
  module MusicIds
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/music_ids.rb CHANGED
@@ -1,5 +1,6 @@
1
- require "music_ids/version"
1
+ require 'music_ids/version'
2
+ require 'music_ids/isrc'
3
+ require 'music_ids/grid'
2
4
 
3
5
  module MusicIds
4
- # Your code goes here...
5
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: music_ids
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Patterson
@@ -88,6 +88,7 @@ files:
88
88
  - bin/console
89
89
  - bin/setup
90
90
  - lib/music_ids.rb
91
+ - lib/music_ids/grid.rb
91
92
  - lib/music_ids/isrc.rb
92
93
  - lib/music_ids/version.rb
93
94
  - music_ids.gemspec