8000 Add ISRC (International Standard Recording Code) · QuantumNovice/python-stdnum@36d723c · GitHub
[go: up one dir, main page]

Skip to content

Commit 36d723c

Browse files
nuno-andrearthurdejong
authored andcommitted
Add ISRC (International Standard Recording Code)
Closes arthurdejong#261
1 parent 48bfd84 commit 36d723c

File tree

2 files changed

+151
-0
lines changed

2 files changed

+151
-0
lines changed

stdnum/isrc.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# isrc.py - functions for International Standard Recording Codes (ISRC)
2+
# coding: utf-8
3+
#
4+
# Copyright (C) 2021 Nuno André Novo
5+
# Copyright (C) 2021 Arthur de Jong
6+
#
7+
# This library is free software; you can redistribute it and/or
8+
# modify it under the terms of the GNU Lesser General Public
9+
# License as published by the Free Software Foundation; either
10+
# version 2.1 of the License, or (at your option) any later version.
11+
#
12+
# This library is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
# Lesser General Public License for more details.
16+
#
17+
# You should have received a copy of the GNU Lesser General Public
18+
# License along with this library; if not, write to the Free Software
19+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20+
# 02110-1301 USA
21+
22+
"""ISRC (International Standard Recording Code).
23+
24+
The ISRC is an international standard code (ISO 3901) for uniquely
25+
identifying sound recordings and music video recordings.
26+
27+
More information:
28+
29+
* https://en.wikipedia.org/wiki/International_Standard_Recording_Code
30+
31+
>>> validate('US-SKG-19-12345')
32+
'USSKG1912345'
33+
>>> validate('XX-SKG-19-12345')
34+
Traceback (most recent call last):
35+
...
36+
InvalidComponent: ...
37+
"""
38+
39+
import re
40+
41+
from stdnum.exceptions import *
42+
from stdnum.isin import _iso_3116_1_country_codes
43+
from stdnum.util import clean
44+
45+
46+
# An ISRC is composed of a country code, a registrant code a year of
47+
# reference and designation code.
48+
_isrc_re = re.compile(
49+
r'^(?P<country>[A-Z]{2})(?P<registrant>[A-Z0-9]{3})(?P<year>[0-9]{2})(?P<record>[0-9]{5})$')
50+
51+
52+
# These special codes are allowed for ISRC
53+
_country_codes = set(_iso_3116_1_country_codes + [
54+
'QM', # US new registrants due to US codes became exhausted
55+
'CP', # reserved for further overflow
56+
'DG', # reserved for further overflow
57+
'ZZ', # International ISRC Agency codes
58+
])
59+
60+
61+
def compact(number):
62+
"""Convert the ISRC to the minimal representation. This strips the
63+
number of any valid separators and removes surrounding whitespace."""
64+
return clean(number, ' -').strip().upper()
65+
66+
67+
def validate(number):
68+
"""Check if the number provided is a valid ISRC. This checks the length,
69+
the alphabet, and the country code but does not check if the registrant
70+
code is known."""
71+
number = compact(number)
72+
if len(number) != 12:
73+
raise InvalidLength()
74+
match = _isrc_re.search(number)
75+
if not match:
76+
raise InvalidFormat()
77+
if match.group('country') not in _country_codes:
78+
raise InvalidComponent()
79+
return number
80+
81+
82+
def is_valid(number):
83+
"""Check if the number provided is a valid ISRC."""
84+
try:
85+
return bool(validate(number))
86+
except ValidationError:
87+
return False
88+
89+
90+
def format(number, separator='-'):
91+
"""Reformat the number to the standard presentation format."""
92+
number = compact(number)
93+
return separator.join((number[0:2], number[2:5], number[5:7], number[7:]))

tests/test_isrc.doctest

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
test_isrc.doctest - more detailed doctests for stdnum.isrc module
2+
3+
Copyright (C) 2021 Nuno André Novo
4+
Copyright (C) 2021 Arthur de Jong
5+
6+
This library is free software; you can redistribute it and/or
7+
modify it under the terms of the GNU Lesser General Public
8+
License as published by the Free Software Foundation; either
9+
version 2.1 of the License, or (at your option) any later version.
10+
11+
This library is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
Lesser General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public
17+
License along with this library; if not, write to the Free Software
18+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19+
02110-1301 USA
20+
21+
22+
This file contains more detailed doctests for the stdnum.isrc module. It
23+
tries to test more corner cases and detailed functionality that is not
24+
really useful as module documentation.
25+
26+
>>> from stdnum import isrc
27+
28+
29+
These are normal variations that should just work.
30+
31+
>>> isrc.validate('US-SKG-19-12345')
32+
'USSKG1912345'
33+
>>> isrc.validate('USSKG1912345')
34+
'USSKG1912345'
35+
>>> isrc.validate('us-skg1912345')
36+
'USSKG1912345'
37+
38+
39+
Tests for mangling and incorrect country codes.
40+
41+
>>> isrc.validate('US-SKG-19-123456')
42+
Traceback (most recent call last):
43+
...
44+
InvalidLength: ...
45+
>>> isrc.validate('US-SKG-19-1234*')
46+
Traceback (most recent call last):
47+
...
48+
InvalidFormat: ...
49+
>>> isrc.validate('XX-SKG-19-12345')
50+
Traceback (most recent call last):
51+
...
52+
InvalidComponent: ...
53+
54+
55+
Formatting tests.
56+
57+
>>> isrc.format('USSKG1912345')
58+
'US-SKG-19-12345'

0 commit comments

Comments
 (0)
0