Merge branch 'better-beets'.

Makes beets actually usable (and configurable) on Nix(OS), if you want
to use more plugins rather than just plain lookup of tracks based on
(fuzzy) string matching.

This also changes the derivation name from "python2.7-beets" to just
"beets".

* Commit summary:
  beets: Check dependencies on activated plugins.
  beets: Check plugin definitions against package.
  beets: Use audiotools backend for replaygain.
  beets: Allow to configure plugin dependencies.
  beets: Switch to using fetchFromGitHub.
  python: Add new package audiotools.
  python: Add new package discogs_client.
  python: Add pyacoustid and dependencies.
  python/mutagen: Update to upstream version 1.27.
  mp3gain: Fix output path bin directory.
  beets: Add myself to maintainers.
  beets: Update to new upstream version 1.3.9.
  beets: Move into its own package directory.
This commit is contained in:
aszlig 2014-12-30 23:21:57 +01:00
commit 880c985f27
No known key found for this signature in database
GPG Key ID: D0EBD0EC8C2DC961
6 changed files with 297 additions and 44 deletions

View File

@ -14,8 +14,7 @@ stdenv.mkDerivation {
buildFlags = [ "OSTYPE=linux" ];
installPhase = ''
mkdir -p $out/usr/bin
cp mp3gain $out/usr/bin
install -vD mp3gain "$out/bin/mp3gain"
'';
meta = {

View File

@ -0,0 +1,177 @@
{ stdenv, fetchFromGitHub, writeScript
, buildPythonPackage, pythonPackages, python
, enableAcoustid ? true
, enableBeatport ? true
, enableDiscogs ? true
, enableEchonest ? true
, enableFetchart ? true
, enableLastfm ? true
, enableMpd ? true
, enableReplaygain ? true
, enableWeb ? true
, bashInteractive, bashCompletion
}:
assert enableAcoustid -> pythonPackages.pyacoustid != null;
assert enableBeatport -> pythonPackages.responses != null;
assert enableDiscogs -> pythonPackages.discogs_client != null;
assert enableEchonest -> pythonPackages.pyechonest != null;
assert enableFetchart -> pythonPackages.responses != null;
assert enableLastfm -> pythonPackages.pylast != null;
assert enableMpd -> pythonPackages.mpd != null;
assert enableReplaygain -> pythonPackages.audiotools != null;
assert enableWeb -> pythonPackages.flask != null;
with stdenv.lib;
let
optionalPlugins = {
beatport = enableBeatport;
chroma = enableAcoustid;
discogs = enableDiscogs;
echonest = enableEchonest;
echonest_tempo = enableEchonest;
fetchart = enableFetchart;
lastgenre = enableLastfm;
lastimport = enableLastfm;
mpdstats = enableMpd;
mpdupdate = enableMpd;
replaygain = enableReplaygain;
web = enableWeb;
};
pluginsWithoutDeps = [
"bench" "bpd" "bpm" "bucket" "convert" "duplicates" "embedart" "freedesktop"
"fromfilename" "ftintitle" "fuzzy" "ihate" "importadded" "importfeeds"
"info" "inline" "keyfinder" "lyrics" "mbcollection" "mbsync" "missing"
"play" "random" "rewrite" "scrub" "smartplaylist" "spotify" "the" "types"
"zero"
];
enabledOptionalPlugins = attrNames (filterAttrs (_: id) optionalPlugins);
allPlugins = pluginsWithoutDeps ++ attrNames optionalPlugins;
allEnabledPlugins = pluginsWithoutDeps ++ enabledOptionalPlugins;
# Discogs plugin wants to have an API token, so skip install checks.
allTestablePlugins = remove "discogs" allEnabledPlugins;
testShell = "${bashInteractive}/bin/bash --norc";
completion = "${bashCompletion}/share/bash-completion/bash_completion";
in buildPythonPackage rec {
name = "beets-${version}";
version = "1.3.9";
namePrefix = "";
src = fetchFromGitHub {
owner = "sampsyo";
repo = "beets";
rev = "v${version}";
sha256 = "1srhkiyjqx6i3gn20ihf087l5pa77yh5b81ivc52lj491fda7xqk";
};
propagatedBuildInputs = [
pythonPackages.enum34
pythonPackages.munkres
pythonPackages.musicbrainzngs
pythonPackages.mutagen
pythonPackages.pyyaml
pythonPackages.unidecode
python.modules.sqlite3
python.modules.readline
] ++ optional enableAcoustid pythonPackages.pyacoustid
++ optional (enableBeatport || enableFetchart) pythonPackages.requests2
++ optional enableDiscogs pythonPackages.discogs_client
++ optional enableEchonest pythonPackages.pyechonest
++ optional enableLastfm pythonPackages.pylast
++ optional enableMpd pythonPackages.mpd
++ optional enableReplaygain pythonPackages.audiotools
++ optional enableWeb pythonPackages.flask;
buildInputs = with pythonPackages; [
beautifulsoup4
flask
mock
nose
pyechonest
pylast
rarfile
requests2
responses
];
patches = [
./mediafile-codec-fix.patch
./replaygain-default-audiotools.patch
];
postPatch = ''
sed -i -e '/assertIn.*item.*path/d' test/test_info.py
echo echo completion tests passed > test/test_completion.sh
sed -i -e '/^BASH_COMPLETION_PATHS *=/,/^])$/ {
/^])$/i u"${completion}"
}' beets/ui/commands.py
'';
doCheck = true;
preCheck = ''
(${concatMapStrings (s: "echo \"${s}\";") allPlugins}) \
| sort -u > plugins_defined
find beetsplug -mindepth 1 \
\! -path 'beetsplug/__init__.py' -a \
\( -name '*.py' -o -path 'beetsplug/*/__init__.py' \) -print \
| sed -n -re 's|^beetsplug/([^/.]+).*|\1|p' \
| sort -u > plugins_available
if ! mismatches="$(diff -y plugins_defined plugins_available)"; then
echo "The the list of defined plugins (left side) doesn't match" \
"the list of available plugins (right side):" >&2
echo "$mismatches" >&2
exit 1
fi
'';
checkPhase = ''
runHook preCheck
BEETS_TEST_SHELL="${testShell}" \
BASH_COMPLETION_SCRIPT="${completion}" \
HOME="$(mktemp -d)" \
nosetests -v
runHook postCheck
'';
doInstallCheck = true;
installCheckPhase = ''
runHook preInstallCheck
tmphome="$(mktemp -d)"
EDITOR="${writeScript "beetconfig.sh" ''
#!${stdenv.shell}
cat > "$1" <<CFG
plugins: ${concatStringsSep " " allTestablePlugins}
musicbrainz:
user: dummy
pass: dummy
CFG
''}" HOME="$tmphome" "$out/bin/beet" config -e
EDITOR=true HOME="$tmphome" "$out/bin/beet" config -e
runHook postInstallCheck
'';
meta = {
homepage = http://beets.radbox.org;
description = "Music tagger and library organizer";
license = stdenv.lib.licenses.mit;
maintainers = with stdenv.lib.maintainers; [ iElectric aszlig ];
};
}

View File

@ -0,0 +1,25 @@
From 903e88a228d6bd93bd1884c59dd23dd9f04a1199 Mon Sep 17 00:00:00 2001
From: Adrian Sampson <adrian@radbox.org>
Date: Wed, 26 Nov 2014 19:04:40 -0800
Subject: [PATCH] Fix codec reference in MediaFile (fix #1117)
---
beets/mediafile.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/beets/mediafile.py b/beets/mediafile.py
index ce42621..a459e09 100644
--- a/beets/mediafile.py
+++ b/beets/mediafile.py
@@ -1340,8 +1340,9 @@ def __init__(self, path, id3v23=False):
raise FileTypeError(path)
elif (type(self.mgfile).__name__ == 'M4A' or
type(self.mgfile).__name__ == 'MP4'):
- if hasattr(self.mgfile.info, 'codec'):
- if self.mgfile.codec and self.mgfile.codec.startswith('alac'):
+ info = self.mgfile.info
+ if hasattr(info, 'codec'):
+ if info.codec and info.codec.startswith('alac'):
self.type = 'alac'
else:
self.type = 'aac'

View File

@ -0,0 +1,17 @@
diff --git a/beetsplug/replaygain.py b/beetsplug/replaygain.py
index 40b3a3a..9b54a5a 100644
--- a/beetsplug/replaygain.py
+++ b/beetsplug/replaygain.py
@@ -627,11 +627,10 @@ class ReplayGainPlugin(BeetsPlugin):
super(ReplayGainPlugin, self).__init__()
self.import_stages = [self.imported]
- # default backend is 'command' for backward-compatibility.
self.config.add({
'overwrite': False,
'auto': True,
- 'backend': u'command',
+ 'backend': u'audiotools',
'targetlevel': 89,
})

View File

@ -757,6 +757,8 @@ let
beanstalkd = callPackage ../servers/beanstalkd { };
beets = callPackage ../tools/audio/beets { };
bgs = callPackage ../tools/X11/bgs { };
biber = callPackage ../tools/typesetting/biber {

View File

@ -531,6 +531,36 @@ let
};
});
audioread = buildPythonPackage rec {
name = "audioread-1.2.1";
src = pkgs.fetchurl {
url = "https://pypi.python.org/packages/source/a/audioread/${name}.tar.gz";
md5 = "01a80357f38dbd9bf8d7403802df89ac";
};
meta = {
description = "Cross-platform audio decoding";
homepage = "https://github.com/sampsyo/audioread";
license = stdenv.lib.licenses.mit;
};
};
audiotools = buildPythonPackage rec {
name = "audiotools-2.22";
src = pkgs.fetchurl {
url = "mirror://sourceforge/audiotools/${name}.tar.gz";
sha256 = "1c52pggsbxdbj8h92njf4h0jgfndh4yv58ad723pidys47nw1y71";
};
meta = {
description = "Utilities and Python modules for handling audio.";
homepage = "http://audiotools.sourceforge.net/";
license = stdenv.lib.licenses.gpl2Plus;
};
};
autopep8 = buildPythonPackage (rec {
name = "autopep8-1.0.4";
@ -789,44 +819,6 @@ let
};
};
beets = buildPythonPackage rec {
name = "beets-1.3.6";
src = pkgs.fetchurl {
url = "http://pypi.python.org/packages/source/b/beets/${name}.tar.gz";
md5 = "59615a54b3ac3983159e77ff9dda373e";
};
# tests depend on $HOME setting
preConfigure = "export HOME=$TMPDIR";
propagatedBuildInputs =
[ self.pyyaml
self.unidecode
self.mutagen
self.munkres
self.musicbrainzngs
self.enum34
self.pylast
self.rarfile
self.flask
modules.sqlite3
modules.readline
];
buildInputs = with self; [ mock pyechonest six responses nose ];
# 10 tests are failing
doCheck = false;
meta = {
homepage = http://beets.radbox.org;
description = "Music tagger and library organizer";
license = licenses.mit;
maintainers = [ stdenv.lib.maintainers.iElectric ];
};
};
circus = buildPythonPackage rec {
name = "circus-0.11.1";
@ -2191,6 +2183,23 @@ let
};
};
discogs_client = buildPythonPackage rec {
name = "discogs-client-2.0.2";
src = pkgs.fetchurl {
url = "https://pypi.python.org/packages/source/d/discogs-client/${name}.tar.gz";
md5 = "2cc57e1d134aa93404e779b9311676fa";
};
propagatedBuildInputs = with self; [ oauth2 requests ];
meta = {
description = "Official Python API client for Discogs";
license = licenses.bsd2;
homepage = "https://github.com/discogs/discogs_client";
};
};
dns = buildPythonPackage rec {
name = "dnspython-${version}";
version = "1.12.0";
@ -5760,15 +5769,15 @@ let
};
mutagen = buildPythonPackage (rec {
name = "mutagen-1.23";
name = "mutagen-1.27";
src = pkgs.fetchurl {
url = "http://pypi.python.org/packages/source/m/mutagen/${name}.tar.gz";
sha256 = "12f70aaf5ggdzll76bhhkn64b27xy9s1acx417dbsaqnnbis8s76";
md5 = "6a9bb5cc33214add35348f1bb3448340";
};
# one unicode test fails
doCheck = false;
# Needed for tests only
buildInputs = [ pkgs.faad2 pkgs.flac pkgs.vorbisTools pkgs.liboggz ];
meta = {
description = "Python multimedia tagging library";
@ -6984,6 +6993,30 @@ let
};
pyacoustid = buildPythonPackage rec {
name = "pyacoustid-1.1.0";
src = pkgs.fetchurl {
url = "https://pypi.python.org/packages/source/p/pyacoustid/${name}.tar.gz";
md5 = "b27c714d530300b917eb869726334226";
};
propagatedBuildInputs = with self; [ requests audioread ];
postPatch = ''
sed -i \
-e '/^FPCALC_COMMAND *=/s|=.*|= "${pkgs.chromaprint}/bin/fpcalc"|' \
acoustid.py
'';
meta = {
description = "Bindings for Chromaprint acoustic fingerprinting";
homepage = "https://github.com/sampsyo/pyacoustid";
license = stdenv.lib.licenses.mit;
};
};
pyalgotrade = buildPythonPackage {
name = "pyalogotrade-0.16";