Merge branch 'master' into always_default_drive

Conflicts:
	picard/util/cdrom.py
This commit is contained in:
Johannes Dewender
2013-12-30 01:11:49 +01:00
26 changed files with 59 additions and 50 deletions

View File

@@ -21,7 +21,7 @@ from collections import deque
from functools import partial
from PyQt4 import QtCore
from picard import config, log
from picard.const import ACOUSTID_KEY, FPCALC_NAMES
from picard.const import FPCALC_NAMES
from picard.util import find_executable
from picard.webservice import XmlNode

View File

@@ -24,10 +24,9 @@ from heapq import heappush, heappop
from PyQt4 import QtCore
from picard import config
from picard.metadata import Metadata
from picard.similarity import similarity2, similarity
from picard.similarity import similarity
from picard.ui.item import Item
from picard.util import format_time
from picard.mbxml import artist_credit_from_node
class Cluster(QtCore.QObject, Item):
@@ -190,10 +189,10 @@ class Cluster(QtCore.QObject, Item):
albumDict.add(album)))
artist_cluster_engine = ClusterEngine(artistDict)
artist_cluster = artist_cluster_engine.cluster(threshold)
artist_cluster_engine.cluster(threshold)
album_cluster_engine = ClusterEngine(albumDict)
album_cluster = album_cluster_engine.cluster(threshold)
album_cluster_engine.cluster(threshold)
# Arrange tracks into albums
albums = {}
@@ -459,7 +458,5 @@ class ClusterEngine(object):
self.idClusterIndex[match] = match0
del self.clusterBins[match1]
return self.clusterBins
def can_refresh(self):
return False

View File

@@ -20,7 +20,7 @@
from operator import itemgetter
from PyQt4 import QtCore
from picard import (PICARD_APP_NAME, PICARD_ORG_NAME, PICARD_VERSION,
version_to_string, version_from_string, log)
version_to_string, version_from_string)
from picard.util import LockableObject, rot13

View File

@@ -19,7 +19,6 @@
import os
import sys
import re
# Install gettext "noop" function in case const.py gets imported directly.
import __builtin__

View File

@@ -24,10 +24,9 @@
import json
import re
import traceback
import picard.webservice
from functools import partial
from picard import config, log
from picard.metadata import Metadata, is_front_image
from picard.metadata import is_front_image
from picard.util import mimetype, parse_amazon_url
from picard.const import CAA_HOST, CAA_PORT
from PyQt4.QtCore import QUrl, QObject

View File

@@ -29,11 +29,9 @@ from operator import itemgetter
from collections import defaultdict
from PyQt4 import QtCore
from picard import config, log
from picard.track import Track
from picard.metadata import Metadata
from picard.ui.item import Item
from picard.script import ScriptParser
from picard.similarity import similarity2
from picard.util import (
decode_filename,
encode_filename,
@@ -144,7 +142,7 @@ class File(QtCore.QObject, Item):
def has_error(self):
return self.state == File.ERROR
def _load(self):
def _load(self, filename):
"""Load metadata from the file."""
raise NotImplementedError
@@ -359,8 +357,8 @@ class File(QtCore.QObject, Item):
# image multiple times
if (os.path.exists(new_filename) and
os.path.getsize(new_filename) == len(data)):
log.debug("Identical file size, not saving %r", image_filename)
continue
log.debug("Identical file size, not saving %r", image_filename)
continue
log.debug("Saving cover images to %r", image_filename)
new_dirname = os.path.dirname(image_filename)
if not os.path.isdir(new_dirname):

View File

@@ -22,7 +22,7 @@ import struct
from struct import pack, unpack
import mutagen
from mutagen._util import insert_bytes
from mutagen.id3 import ID3, Frame, Frames, Frames_2_2, TextFrame, TORY, \
from mutagen.id3 import ID3, Frames, Frames_2_2, TextFrame, TORY, \
TYER, TIME, APIC, IPLS, TDAT, BitPaddedInt, MakeID3v1

View File

@@ -1,3 +1,22 @@
# -*- coding: utf-8 -*-
#
# Picard, the next-generation MusicBrainz tagger
# 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
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import gettext
import locale
import os.path

View File

@@ -62,7 +62,7 @@ class Logger(object):
for func in self._receivers:
try:
thread.to_main(func, level, time, message)
except Exception as e:
except:
import traceback
traceback.print_exc()

View File

@@ -21,8 +21,7 @@ import traceback
from collections import defaultdict
from functools import partial
from itertools import combinations
from PyQt4 import QtCore
from picard import config, log
from picard import log
from picard.metadata import Metadata
from picard.dataobj import DataObject
from picard.mbxml import media_formats_from_node, label_info_from_node

View File

@@ -26,7 +26,6 @@ import re
import shutil
import signal
import sys
from collections import deque
from functools import partial
from itertools import chain
@@ -61,7 +60,6 @@ from picard.track import Track, NonAlbumTrack
from picard.releasegroup import ReleaseGroup
from picard.collection import load_user_collections
from picard.ui.mainwindow import MainWindow
from picard.ui.itemviews import BaseTreeView
from picard.plugin import PluginManager
from picard.acoustidmanager import AcoustIDManager
from picard.util import (

View File

@@ -50,7 +50,8 @@ class CDLookupDialog(QtGui.QDialog):
item.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(release.id))
self.ui.release_list.setCurrentItem(self.ui.release_list.topLevelItem(0))
self.ui.ok_button.setEnabled(True)
[self.ui.release_list.resizeColumnToContents(i) for i in range(self.ui.release_list.columnCount() - 1)]
for i in range(self.ui.release_list.columnCount() - 1):
self.ui.release_list.resizeColumnToContents(i)
# Sort by descending date, then ascending country
self.ui.release_list.sortByColumn(3, QtCore.Qt.AscendingOrder)
self.ui.release_list.sortByColumn(2, QtCore.Qt.DescendingOrder)

View File

@@ -1,4 +1,4 @@
# -*- coding: UTF-8 -*-
# -*- coding: utf-8 -*-
#
# Picard, the next-generation MusicBrainz tagger
# Copyright (C) 2006-2007 Lukáš Lalinský

View File

@@ -18,7 +18,6 @@
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import QIcon
from picard import config
from picard.util import icontheme
from picard.ui.ui_infostatus import Ui_InfoStatus

View File

@@ -308,7 +308,9 @@ class BaseTreeView(QtGui.QTreeWidget):
action.setChecked(True)
action.triggered.connect(partial(obj.switch_release_version, version["id"]))
_add_other_versions() if obj.release_group.loaded else \
if obj.release_group.loaded:
_add_other_versions()
else:
obj.release_group.load_versions(_add_other_versions)
releases_menu.setEnabled(True)
else:

View File

@@ -22,7 +22,6 @@ from PyQt4 import QtCore, QtGui
import sys
import os.path
from functools import partial
from picard import config, log
from picard.file import File
from picard.track import Track

View File

@@ -290,7 +290,9 @@ class MetadataBox(QtGui.QTableWidget):
self.set_tag_values(tag, [""])
def remove_selected_tags(self):
(self.remove_tag(tag) for tag in self.selected_tags() if self.tag_is_removable(tag))
for tag in self.selected_tags():
if self.tag_is_removable(tag):
self.remove_tag(tag)
def tag_is_removable(self, tag):
return self.tag_diff.status[tag] & TagStatus.NotRemovable == 0

View File

@@ -19,7 +19,6 @@
from PyQt4 import QtCore, QtGui
from picard import config
from picard.plugin import ExtensionPoint
from picard.util import webbrowser2
from picard.ui.util import StandardButton
from picard.ui.options import (

View File

@@ -18,7 +18,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import os
from PyQt4 import QtCore, QtGui
from PyQt4 import QtGui
from picard import config
from picard.util import webbrowser2, find_executable
from picard.const import FPCALC_NAMES

View File

@@ -17,7 +17,6 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
from PyQt4 import QtCore
from picard import config
from picard.ui.options import OptionsPage, register_options_page
from picard.ui.ui_options_metadata import Ui_MetadataOptionsPage

View File

@@ -17,7 +17,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
from PyQt4 import QtCore, QtGui
from PyQt4 import QtGui
from picard import config
from picard.ui.ui_passworddialog import Ui_PasswordDialog
from picard.util import rot13

View File

@@ -18,8 +18,6 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import locale
import picard.i18n
"""
Helper class to convert bytes to human-readable form
@@ -46,26 +44,26 @@ _BYTES_STRINGS_I18N = (
)
def decimal(number, prec=1):
def decimal(number, scale=1):
"""
Convert bytes to short human-readable string, decimal mode
>>> [decimal(n) for n in [1000, 1024, 15500]]
['1 kB', '1 kB', '15.5 kB']
"""
return short_string(int(number), 1000)
return short_string(int(number), 1000, scale)
def binary(number, prec=1):
def binary(number, scale=1):
"""
Convert bytes to short human-readable string, binary mode
>>> [binary(n) for n in [1000, 1024, 15500]]
['1000 B', '1 KiB', '15.1 KiB']
"""
return short_string(int(number), 1024, prec)
return short_string(int(number), 1024, scale)
def short_string(number, multiple, prec=1):
def short_string(number, multiple, scale=1):
"""
Returns short human-readable string for `number` bytes
>>> [short_string(n, 1024, 2) for n in [1000, 1100, 15500]]
@@ -75,12 +73,12 @@ def short_string(number, multiple, prec=1):
"""
num, unit = calc_unit(number, multiple)
n = int(num)
nr = round(num, prec)
nr = round(num, scale)
if n == nr or unit == 'B':
fmt = '%d'
num = n
else:
fmt = '%%0.%df' % prec
fmt = '%%0.%df' % scale
num = nr
fmtnum = locale.format(fmt, num)
return _("%s " + unit) % fmtnum
@@ -118,8 +116,3 @@ def calc_unit(number, multiple=1000):
return (sign * n, suffix)
else:
n /= multiple
if __name__ == "__main__":
import doctest
doctest.testmod()

View File

@@ -54,10 +54,12 @@ else:
# setting uses a text field instead of a drop-down
AUTO_DETECT_DRIVES = False
def _split_values(s):
"""split a space separated list"""
return QString(s).trimmed().split(QRegExp("\\s+"), QString.SkipEmptyParts)
def get_cdrom_drives():
"""List available disc drives on the machine
"""
@@ -90,10 +92,11 @@ def get_cdrom_drives():
elif key == 'Can play audio':
drive_audio_caps = [v == '1'
for v in _split_values(values)]
break # no need to continue past this line
line = cdinfo.readLine()
# Show only drives that are capable of playing audio
for drive in drive_names:
if drive_audio_caps[drive_names.indexOf(drive)]:
for index, drive in enumerate(drive_names):
if drive_audio_caps[index]:
device = u'/dev/%s' % drive
symlink_target = QFile.symLinkTarget(device)
if symlink_target != '':

View File

@@ -19,7 +19,7 @@
import sys
import traceback
from PyQt4.QtCore import QThreadPool, QRunnable, QCoreApplication, QEvent
from PyQt4.QtCore import QRunnable, QCoreApplication, QEvent
class ProxyToMainEvent(QEvent):

View File

@@ -392,7 +392,7 @@ class XmlWebService(QtCore.QObject):
query = []
for name, value in kwargs.items():
if name == 'limit':
filters.append((name, value))
filters.append((name, str(value)))
else:
value = _escape_lucene_query(value).strip().lower()
if value:

View File

@@ -30,8 +30,11 @@ class Testbytes2human(unittest.TestCase):
self.assertEqual(bytes2human.binary(45682), '44.6 KiB')
self.assertEqual(bytes2human.binary(-45682), '-44.6 KiB')
self.assertEqual(bytes2human.binary(-45682, 2), '-44.61 KiB')
self.assertEqual(bytes2human.decimal(45682), '45.7 kB')
self.assertEqual(bytes2human.decimal(45682, 2), '45.68 kB')
self.assertEqual(bytes2human.decimal(9223372036854775807), '9223.4 PB')
self.assertEqual(bytes2human.decimal(9223372036854775807, 3), '9223.372 PB')
self.assertEqual(bytes2human.decimal(123.6), '123 B')
self.assertRaises(ValueError, bytes2human.decimal, 'xxx')
self.assertRaises(ValueError, bytes2human.decimal, '123.6')