mirror of
https://github.com/fergalmoran/picard.git
synced 2026-02-26 17:43:59 +00:00
Merge branch 'master' into always_default_drive
Conflicts: picard/util/cdrom.py
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
|
||||
# Install gettext "noop" function in case const.py gets imported directly.
|
||||
import __builtin__
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Picard, the next-generation MusicBrainz tagger
|
||||
# Copyright (C) 2006-2007 Lukáš Lalinský
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 != '':
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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')
|
||||
|
||||
Reference in New Issue
Block a user