from org.diplodocus import flac, taglib
from org.diplodocus.util import run_or_die
+from flac_archive.tags import Tags
+
################################################################################
# The child processes
return args
-# XXX other things should usue this; flac files, for example, should
-# get PART as part of the filelname, same as mp3s.
-class Tags(object):
- def __init__(self):
- self._global = {}
- self._tags = {}
- def __len__(self):
- # All files have at least one track.
- return max(1, len(self._tags))
- def get(self, key, track=None):
- key = key.upper()
- try:
- try:
- return self._tags[track][key]
- except KeyError:
- return self._global[key]
- except KeyError:
- return None
- def gets(self, key, track=None):
- value = self.get(key, track)
- if value == None:
- return None
- return '\n'.join(value)
- def set(self, key, value, track=None):
- key = key.upper()
- if track == None:
- tags = self._global
- else:
- try:
- tags = self._tags[track]
- except KeyError:
- tags = self._tags[track] = {}
- if key not in tags:
- tags[key] = []
- tags[key].append(value)
-
def get_tags(fn):
"""Return the ARTIST, ALBUM, and DATE tags followed by the TITLE tags
in the file FN."""
tags = Tags()
p = Popen(['metaflac', '--export-tags-to=-', fn], stdout=PIPE)
- for line in (x.rstrip() for x in p.stdout):
- (tag, value) = line.split('=', 1)
-
- m = re.search(r'\[([0-9]+)]$', tag)
- if m != None:
- tag = tag[:m.start()]
- track = int(m.group(1))
- else:
- track = None
+ tags.load(p.stdout)
- tags.set(tag, value, track)
# XXX dataloss! check status
status = p.wait()
--- /dev/null
+import re
+
+class Tags(object):
+ def __init__(self):
+ self._global = {}
+ self._tracks = {}
+
+ def __len__(self):
+ # All files have at least one track.
+ return max(1, len(self._tracks))
+
+ def set(self, key, value, track=None):
+ key = key.upper()
+ if track == None:
+ tags = self._global
+ else:
+ try:
+ tags = self._tracks[track]
+ except KeyError:
+ tags = self._tracks[track] = {}
+ if key not in tags:
+ tags[key] = []
+ tags[key].append(value)
+
+ def load(self, fp):
+ for line in (x.rstrip() for x in fp):
+ (tag, value) = line.split('=', 1)
+
+ m = re.search(r'\[([0-9]+)]$', tag)
+ if m != None:
+ tag = tag[:m.start()]
+ track = int(m.group(1))
+ else:
+ track = None
+
+ self.set(tag, value, track)
+
+ def get(self, key, track=None):
+ result = []
+ key = key.upper()
+ try:
+ result.extend(self._global[key])
+ except KeyError:
+ pass
+ try:
+ result.extend(self._tracks[track][key])
+ except KeyError:
+ pass
+ return result
+
+ def gets(self, key, track=None, separator='\n'):
+ value = self.get(key, track)
+ if len(value) == 0:
+ return None
+ return separator.join(value)
+
+ def all(self):
+ result = []
+ for (tag, values) in self._global.iteritems():
+ for value in values:
+ result.append('='.join([tag, value]))
+ for (track, tags) in self._tracks.iteritems():
+ for (tag, values) in tags.iteritems():
+ for value in values:
+ result.append('%s[%d]=%s' % (tag, track, value))
+ return result
+
+ def track(self, track):
+ result = ['TRACKNUMBER=%d' % (track,)]
+ for (tag, values) in self._global.iteritems():
+ for value in values:
+ result.append('='.join([tag, value]))
+ for (this_track, tags) in self._tracks.iteritems():
+ if this_track != track:
+ continue
+ for (tag, values) in tags.iteritems():
+ for value in values:
+ result.append('%s=%s' % (tag, value))
+ return result
taglib_libs = Popen([taglib_config, '--libs'],
stdout=PIPE).communicate()[0].strip().split()
-setup(name='flac-archive',
- version='6',
+setup(name='flac-archive', version='6',
+ license='MIT',
+
+ packages=['flac_archive'],
scripts=[
'fa-flacd',
'fa-rip',
--- /dev/null
+#! /usr/bin/env zsh
+
+dir=$(cd $(dirname $0) && pwd)
+top=$(cd ${dir}/.. && pwd)
+export PYTHONPATH="${top}:${PYTHONPATH}"
+
+typeset -a coverage_init
+typeset -a coverage
+: ${PYTHON:=python2.4}
+while getopts 'C:cp:' ch; do
+ case ${ch} in
+ C)
+ coverage_report=${OPTARG}
+ ;;
+ c)
+ coverage_init=(${PYTHON} ${top}/coverage.py -e)
+ coverage=(${top}/coverage.py -x)
+ ;;
+ p)
+ PYTHON=${OPTARG}
+ ;;
+ ?)
+ echo ${help}
+ exit -1
+ ;;
+ esac
+done
+shift $((${OPTIND} - 1))
+
+################################################################################
+if [[ -n ${coverage_report} ]]; then
+ if [[ ${coverage_report} == '.' ]]; then
+ cov=()
+ coverage_report=(flac_archive/*.py)
+ else
+ cov=(-c "${coverage_report}.coverage")
+ fi
+
+ opts=("$@")
+ [[ ${#opts} == 0 ]] && opts=(-mr)
+ exec ${PYTHON} ${top}/coverage.py ${cov} ${opts} ${coverage_report}
+fi
+
+################################################################################
+
+failed=0
+
+${coverage_init}
+if [[ -n ${coverage} ]] && [[ $# -eq 1 ]]; then
+ out=$1.coverage
+ rm -f ${out}
+ exec ${PYTHON} ${coverage} -c ${out} ${1/flac_archive\//test/test}
+fi
+${PYTHON} ${coverage} ${dir}/test.py || (( failed++ ))
+
+setopt EXTENDED_GLOB
+if [[ -n ${coverage} ]]; then
+ for i in ${dir}/test[a-z]*.py; do
+ out=${top}/flac_archive/${i#${dir}/test}.coverage
+ rm -f ${out}
+ ${PYTHON} ${coverage} -c ${out} -x ${i}
+ done
+fi
+
+exit ${failed}
--- /dev/null
+from unittest import main
+
+from testtags import *
+
+if __name__ == '__main__':
+ main()
--- /dev/null
+#! /usr/bin/python2.4
+
+import cStringIO, sys
+
+from unittest import TestCase, main
+
+sys.path.insert(0, '.')
+from flac_archive.tags import Tags
+
+_tags1 = """ARTIST=Basil
+ALBUM=The Rat
+DATE=1994
+TITLE[1]=Song 1
+ARTIST[1]=Manuel
+TITLE[2]=Song 2
+TITLE[3]=Song 3
+PART[3]=Part the First
+"""
+
+class TagsTestCase(TestCase):
+ def testBasic(self):
+ tags = Tags()
+ tags.load(cStringIO.StringIO(_tags1))
+ self.assertEquals(tags.gets('ARTIST'), 'Basil')
+ self.assertEquals(tags.gets('ARTIST', 1), 'Basil\nManuel')
+ self.assertEquals(tags.gets('ARTIST', 1, ' foo ' ), 'Basil foo Manuel')
+ self.assertEquals(tags.gets('ARTIST', 2), 'Basil')
+
+ self.assertEquals(sorted(tags.all()),
+ sorted(_tags1.strip().split('\n')))
+ self.assertEquals(sorted(tags.track(1)),
+ ['ALBUM=The Rat', 'ARTIST=Basil', 'ARTIST=Manuel',
+ 'DATE=1994', 'TITLE=Song 1', 'TRACKNUMBER=1'])
+ self.assertEquals(sorted(tags.track(3)),
+ ['ALBUM=The Rat', 'ARTIST=Basil', 'DATE=1994',
+ 'PART=Part the First', 'TITLE=Song 3',
+ 'TRACKNUMBER=3'])
+
+if __name__ == '__main__':
+ main()