Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
81f388fe4ab7fe591d68cc3f14753247eaa4992d
4 changes: 4 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ jobs:
uses: astral-sh/ruff-action@v3
with:
args: "check --output-format=github"
- name: Ruff format check
uses: astral-sh/ruff-action@v3
with:
args: "format --diff"
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ repos:
hooks:
- id: ruff-check
args: [--fix]
- id: ruff-format
- repo: local
hooks:
- id: pytest
Expand Down
8 changes: 4 additions & 4 deletions discid/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
and will raise :exc:`OSError` when libdiscid is not found.
"""

from discid.disc import read, put, Disc, DiscError, TOCError
from discid.track import Track
from discid.libdiscid import get_default_device
import discid.libdiscid
import discid.disc
import discid.libdiscid
from discid.disc import Disc, DiscError, TOCError, put, read
from discid.libdiscid import get_default_device
from discid.track import Track

__version__ = "1.3.0"

Expand Down
94 changes: 48 additions & 46 deletions discid/disc.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,22 @@
#
# Please submit bug reports to GitHub:
# https://github.com/metabrainz/python-discid/issues
"""Disc class
"""
"""Disc class"""

import re
from ctypes import c_int, c_void_p, c_char_p, c_uint
from ctypes import c_char_p, c_int, c_uint, c_void_p

from discid.libdiscid import _LIB, FEATURES
from discid.util import _encode, _decode, _sectors_to_seconds
from discid.track import Track

from discid.util import _decode, _encode, _sectors_to_seconds

# our implementation of libdiscid's enum discid_feature
_FEATURE_MAPPING = {"read": 1 << 0, "mcn": 1 << 1, "isrc": 1 << 2}


FEATURES_IMPLEMENTED = list(_FEATURE_MAPPING.keys())


def read(device=None, features=None):
"""Reads the TOC from the device given as string
and returns a :class:`Disc` object.
Expand All @@ -54,6 +53,7 @@ def read(device=None, features=None):
disc.read(device, features)
return disc


def put(first, last, disc_sectors, track_offsets):
"""Creates a TOC based on the information given
and returns a :class:`Disc` object.
Expand All @@ -77,23 +77,25 @@ def put(first, last, disc_sectors, track_offsets):


class DiscError(IOError):
""":func:`read` will raise this exception when an error occurred.
"""
""":func:`read` will raise this exception when an error occurred."""

pass


class TOCError(Exception):
""":func:`put` will raise this exception when illegal parameters
are provided.
"""

pass


class Disc(object):
"""The class of the object returned by :func:`read` or :func:`put`.
"""
"""The class of the object returned by :func:`read` or :func:`put`."""

_LIB.discid_new.argtypes = ()
_LIB.discid_new.restype = c_void_p

def __init__(self):
"""The initialization will reserve some memory
for internal data structures.
Expand All @@ -107,22 +109,22 @@ def __str__(self):
assert self._success
return self.id

_LIB.discid_get_error_msg.argtypes = (c_void_p, )
_LIB.discid_get_error_msg.argtypes = (c_void_p,)
_LIB.discid_get_error_msg.restype = c_char_p

def _get_error_msg(self):
"""Get the error message for the last error with the object.
"""
"""Get the error message for the last error with the object."""
error = _LIB.discid_get_error_msg(self._handle)
return _decode(error)


_LIB.discid_read.argtypes = (c_void_p, c_char_p)
_LIB.discid_read.restype = c_int
try:
_LIB.discid_read_sparse.argtypes = (c_void_p, c_char_p, c_uint)
_LIB.discid_read_sparse.restype = c_int
except AttributeError:
pass

def read(self, device=None, features=None):
"""Reads the TOC from the device given as string

Expand All @@ -135,8 +137,9 @@ def read(self, device=None, features=None):
features = []

# only use features implemented on this platform and in this module
self._requested_features = list(set(features) & set(FEATURES)
& set(FEATURES_IMPLEMENTED))
self._requested_features = list(
set(features) & set(FEATURES) & set(FEATURES_IMPLEMENTED)
)

# create the bitmask for libdiscid
c_features = 0
Expand All @@ -145,8 +148,9 @@ def read(self, device=None, features=None):

# device = None will use the default device (internally)
try:
result = _LIB.discid_read_sparse(self._handle, _encode(device),
c_features) == 1
result = (
_LIB.discid_read_sparse(self._handle, _encode(device), c_features) == 1
)
except AttributeError:
result = _LIB.discid_read(self._handle, _encode(device)) == 1
self._success = result
Expand All @@ -156,6 +160,7 @@ def read(self, device=None, features=None):

_LIB.discid_put.argtypes = (c_void_p, c_int, c_int, c_void_p)
_LIB.discid_put.restype = c_int

def put(self, first, last, disc_sectors, track_offsets):
"""Creates a TOC based on the input given.

Expand Down Expand Up @@ -185,27 +190,27 @@ def put(self, first, last, disc_sectors, track_offsets):
raise TOCError(self._get_error_msg())
return self._success


_LIB.discid_get_id.argtypes = (c_void_p, )
_LIB.discid_get_id.argtypes = (c_void_p,)
_LIB.discid_get_id.restype = c_char_p

def _get_id(self):
"""Gets the current MusicBrainz disc ID
"""
"""Gets the current MusicBrainz disc ID"""
assert self._success
result = _LIB.discid_get_id(self._handle)
return _decode(result)

_LIB.discid_get_freedb_id.argtypes = (c_void_p, )
_LIB.discid_get_freedb_id.argtypes = (c_void_p,)
_LIB.discid_get_freedb_id.restype = c_char_p

def _get_freedb_id(self):
"""Gets the current FreeDB disc ID
"""
"""Gets the current FreeDB disc ID"""
assert self._success
result = _LIB.discid_get_freedb_id(self._handle)
return _decode(result)

_LIB.discid_get_submission_url.argtypes = (c_void_p, )
_LIB.discid_get_submission_url.argtypes = (c_void_p,)
_LIB.discid_get_submission_url.restype = c_char_p

def _get_submission_url(self):
"""Give an URL to submit the current TOC
as a new Disc ID to MusicBrainz.
Expand All @@ -215,10 +220,11 @@ def _get_submission_url(self):
return _decode(result)

try:
_LIB.discid_get_toc_string.argtypes = (c_void_p, )
_LIB.discid_get_toc_string.argtypes = (c_void_p,)
_LIB.discid_get_toc_string.restype = c_char_p
except AttributeError:
pass

def _get_toc_string(self):
"""The TOC suitable as value of the `toc parameter`
when accessing the MusicBrainz Web Service.
Expand All @@ -231,38 +237,38 @@ def _get_toc_string(self):
else:
return _decode(result)

_LIB.discid_get_first_track_num.argtypes = (c_void_p, )
_LIB.discid_get_first_track_num.argtypes = (c_void_p,)
_LIB.discid_get_first_track_num.restype = c_int

def _get_first_track_num(self):
"""Gets the first track number
"""
"""Gets the first track number"""
assert self._success
return _LIB.discid_get_first_track_num(self._handle)

_LIB.discid_get_last_track_num.argtypes = (c_void_p, )
_LIB.discid_get_last_track_num.argtypes = (c_void_p,)
_LIB.discid_get_last_track_num.restype = c_int

def _get_last_track_num(self):
"""Gets the last track number
"""
"""Gets the last track number"""
assert self._success
return _LIB.discid_get_last_track_num(self._handle)

_LIB.discid_get_sectors.argtypes = (c_void_p, )
_LIB.discid_get_sectors.argtypes = (c_void_p,)
_LIB.discid_get_sectors.restype = c_int

def _get_sectors(self):
"""Gets the total number of sectors on the disc
"""
"""Gets the total number of sectors on the disc"""
assert self._success
return _LIB.discid_get_sectors(self._handle)

try:
_LIB.discid_get_mcn.argtypes = (c_void_p, )
_LIB.discid_get_mcn.argtypes = (c_void_p,)
_LIB.discid_get_mcn.restype = c_char_p
except AttributeError:
pass

def _get_mcn(self):
"""Gets the current Media Catalogue Number (MCN/UPC/EAN)
"""
"""Gets the current Media Catalogue Number (MCN/UPC/EAN)"""
assert self._success
if "mcn" in self._requested_features:
try:
Expand All @@ -274,7 +280,6 @@ def _get_mcn(self):
else:
return None


@property
def id(self):
"""This is the MusicBrainz :musicbrainz:`Disc ID`,
Expand Down Expand Up @@ -368,15 +373,13 @@ def mcn(self):

@property
def tracks(self):
"""A list of :class:`Track` objects for this Disc.
"""
"""A list of :class:`Track` objects for this Disc."""
tracks = []
assert self._success
for number in range(self.first_track_num, self.last_track_num + 1):
tracks.append(Track(self, number))
return tracks


@property
def cddb_query_string(self):
"""A CDDB query string suitable for querying CDDB servers.
Expand All @@ -394,12 +397,11 @@ def cddb_query_string(self):
)
return cddb_query_string


_LIB.discid_free.argtypes = (c_void_p, )
_LIB.discid_free.argtypes = (c_void_p,)
_LIB.discid_free.restype = None

def _free(self):
"""This will free the internal allocated memory for the object.
"""
"""This will free the internal allocated memory for the object."""
_LIB.discid_free(self._handle)
self._handle = None

Expand Down
Loading