From f742a46846bfbab433ffef2f145db03787ca3c26 Mon Sep 17 00:00:00 2001
From: Laurent Monin
Date: Mon, 17 Jun 2013 20:43:55 +0200
Subject: [PATCH] Use python-discid instead of libdiscid.
Python-discid (http://python-discid.readthedocs.org) is a Python binding of libdiscid.
It resolves http://tickets.musicbrainz.org/browse/PICARD-503
---
picard/disc.py | 127 ++++---------------------------------
picard/ui/options/about.py | 8 +--
2 files changed, 16 insertions(+), 119 deletions(-)
diff --git a/picard/disc.py b/picard/disc.py
index c0fab2815..460669872 100644
--- a/picard/disc.py
+++ b/picard/disc.py
@@ -3,6 +3,7 @@
# Picard, the next-generation MusicBrainz tagger
# Copyright (C) 2007 Lukáš Lalinský
# Copyright (C) 2006 Matthias Friedrich
+# Copyright (C) 2013 Laurent Monin
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -18,21 +19,14 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-import ctypes
-import sys
+# use python-discid (http://python-discid.readthedocs.org/en/latest/)
+import discid
import traceback
from PyQt4 import QtCore
from picard import log
from picard.ui.cdlookup import CDLookupDialog
-_libdiscid = None
-
-
-class DiscError(IOError):
- pass
-
-
class Disc(QtCore.QObject):
def __init__(self):
@@ -40,21 +34,13 @@ class Disc(QtCore.QObject):
self.id = None
self.submission_url = None
- def read(self, device):
- global _libdiscid
- if _libdiscid is None:
- _libdiscid = _openLibrary()
- handle = _libdiscid.discid_new()
- assert handle != 0, "libdiscid: discid_new() returned NULL"
- try:
- res = _libdiscid.discid_read_sparse(handle, device or None, 0)
- except AttributeError:
- res = _libdiscid.discid_read(handle, device or None)
- if res == 0:
- raise DiscError(_libdiscid.discid_get_error_msg(handle))
- self.id = _libdiscid.discid_get_id(handle)
- self.submission_url = _libdiscid.discid_get_submission_url(handle)
- _libdiscid.discid_free(handle)
+ def read(self, device=None):
+ if device is None:
+ device = discid.get_default_device()
+ log.debug(u"Reading CD using device: %r", device)
+ disc = discid.read(device)
+ self.id = disc.id
+ self.submission_url = disc.submission_url
def lookup(self):
self.tagger.xmlws.lookup_discid(self.id, self._lookup_finished)
@@ -74,94 +60,5 @@ class Disc(QtCore.QObject):
dialog.exec_()
-def libdiscid_version():
- global _libdiscid
- try:
- if _libdiscid is None:
- _libdiscid = _openLibrary()
- except NotImplementedError:
- return ""
- try:
- return _libdiscid.discid_get_version_string()
- except AttributeError:
- return "libdiscid"
-
-
-def _openLibrary():
- """Tries to open libdiscid.
-
- @return: a C{ctypes.CDLL} object, representing the opened library
-
- @raise NotImplementedError: if the library can't be opened
- """
-
- # Check to see if we're running in a Mac OS X bundle.
- if sys.platform == 'darwin':
- try:
- libDiscId = ctypes.cdll.LoadLibrary('../Frameworks/libdiscid.0.dylib')
- _setPrototypes(libDiscId)
- return libDiscId
- except OSError, e:
- pass
-
- # This only works for ctypes >= 0.9.9.3. Any libdiscid is found,
- # no matter how it's called on this platform.
- try:
- if hasattr(ctypes.cdll, 'find'):
- libDiscId = ctypes.cdll.find('discid')
- _setPrototypes(libDiscId)
- return libDiscId
- except OSError, e:
- raise NotImplementedError(str(e))
-
- # For compatibility with ctypes < 0.9.9.3 try to figure out the library
- # name without the help of ctypes. We use cdll.LoadLibrary() below,
- # which isn't available for ctypes == 0.9.9.3.
- #
- if sys.platform == 'linux2':
- libName = 'libdiscid.so.0'
- elif sys.platform == 'darwin':
- libName = 'libdiscid.0.dylib'
- elif sys.platform == 'win32':
- libName = 'discid.dll'
- else:
- # This should at least work for Un*x-style operating systems
- libName = 'libdiscid.so.0'
-
- try:
- libDiscId = ctypes.cdll.LoadLibrary(libName)
- _setPrototypes(libDiscId)
- return libDiscId
- except OSError, e:
- raise NotImplementedError('Error opening library: ' + str(e))
-
- assert False # not reached
-
-
-def _setPrototypes(libDiscId):
- ct = ctypes
- libDiscId.discid_new.argtypes = ()
- libDiscId.discid_new.restype = ct.c_void_p
-
- libDiscId.discid_free.argtypes = (ct.c_void_p, )
-
- libDiscId.discid_read.argtypes = (ct.c_void_p, ct.c_char_p)
- try:
- libDiscId.discid_read_sparse.argtypes = (ct.c_void_p, ct.c_char_p,
- ct.c_uint)
- except AttributeError:
- pass
-
- libDiscId.discid_get_error_msg.argtypes = (ct.c_void_p, )
- libDiscId.discid_get_error_msg.restype = ct.c_char_p
-
- libDiscId.discid_get_id.argtypes = (ct.c_void_p, )
- libDiscId.discid_get_id.restype = ct.c_char_p
-
- libDiscId.discid_get_submission_url.argtypes = (ct.c_void_p, )
- libDiscId.discid_get_submission_url.restype = ct.c_char_p
-
- try:
- libDiscId.discid_get_version_string.restype = ct.c_char_p
- except AttributeError:
- pass
+disc_version = 'discid %s, %s' % (discid.__version__,
+ discid.LIBDISCID_VERSION_STRING)
diff --git a/picard/ui/options/about.py b/picard/ui/options/about.py
index 9e8fea09a..61afafc9e 100644
--- a/picard/ui/options/about.py
+++ b/picard/ui/options/about.py
@@ -23,7 +23,7 @@ from picard import PICARD_VERSION_STR_SHORT
from picard.formats import supported_formats
from picard.ui.options import OptionsPage, register_options_page
from picard.ui.ui_options_about import Ui_AboutOptionsPage
-from picard.disc import libdiscid_version
+from picard.disc import disc_version
class AboutOptionsPage(OptionsPage):
@@ -44,8 +44,8 @@ class AboutOptionsPage(OptionsPage):
"version": PICARD_VERSION_STR_SHORT,
"mutagen-version": mutagen_version,
"pyqt-version": pyqt_version,
- "libdiscid-version": libdiscid_version()
- }
+ "disc-version": disc_version
+ }
formats = []
for exts, name in supported_formats():
@@ -65,7 +65,7 @@ Version %(version)s
PyQt %(pyqt-version)s
Mutagen %(mutagen-version)s
-%(libdiscid-version)s
+%(disc-version)s
Supported formats
%(formats)s
Please donate