summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cue.py18
-rw-r--r--cuedump.py (renamed from cueread.py)6
-rwxr-xr-xcutter82
3 files changed, 69 insertions, 37 deletions
diff --git a/cue.py b/cue.py
index 493bee9..4239084 100644
--- a/cue.py
+++ b/cue.py
@@ -27,7 +27,9 @@ class Track:
return sort_iter(self._indexes)
def get(self, attr):
- return self._attrs.get(attr)
+ return self._attrs.get(attr,
+ None if attr in ("pregap", "postgap") else ""
+ )
def isaudio(self):
return self.type == "AUDIO" and self.begin is not None
@@ -38,8 +40,8 @@ class File:
self.type = filetype
self._tracks = []
- def tracks(self, audio_only = False):
- return filter(Track.isaudio if audio_only else None, self._tracks)
+ def tracks(self, filter_audio = True):
+ return filter(Track.isaudio if filter_audio else None, self._tracks)
def add_track(self, track):
self._tracks.append(track)
@@ -48,12 +50,12 @@ class File:
return self.type == "WAVE"
def has_audio_tracks(self):
- return len(list(self.tracks(Track))) > 0
+ return len(list(self.tracks())) > 0
def split_points(self, info):
rate = info.sample_rate * info.bits_per_sample * info.channels // 8
- for track in list(self.tracks(True))[1:]:
+ for track in list(self.tracks())[1:]:
yield rate * track.begin // 75
def __repr__(self):
@@ -67,11 +69,11 @@ class Cue:
def attrs(self):
return sort_iter(self._attrs)
- def files(self, audio_only = False):
- return filter(File.isaudio if audio_only else None, self._files)
+ def files(self, filter_audio = True):
+ return filter(File.isaudio if filter_audio else None, self._files)
def get(self, attr):
- return self._attrs.get(attr)
+ return self._attrs.get(attr, "")
def add_file(self, file):
self._files.append(file)
diff --git a/cueread.py b/cuedump.py
index 902d10c..660603e 100644
--- a/cueread.py
+++ b/cuedump.py
@@ -13,7 +13,7 @@ if sys.version_info.major == 2:
def __getattr__(self, attr):
return getattr(self.stream, attr)
-
+
sys.stdout = Encoded(sys.stdout)
def printf(fmt, *args):
@@ -46,9 +46,9 @@ printf("Cue attributes:\n")
for k, v in cue.attrs():
printf("\t%s = %s\n", k, quote(v))
-for file in cue.files():
+for file in cue.files(filter_audio=False):
printf("File %s %s\n", quote(file.name), file.type)
- for track in file.tracks():
+ for track in file.tracks(filter_audio=False):
printf("\tTrack %d\n", track.number)
pregap = track.get("pregap")
postgap = track.get("postgap")
diff --git a/cutter b/cutter
index 3139502..1da3495 100755
--- a/cutter
+++ b/cutter
@@ -7,6 +7,7 @@ from optparse import OptionParser, OptionGroup
from subprocess import Popen, PIPE
from tempfile import mkdtemp
from shutil import copyfile
+from itertools import chain
import sys
import os
@@ -74,7 +75,7 @@ def print_cue(cue):
for k, v in cue.attrs():
printf("%s: %s\n", k.upper(), quote(v))
- for file in cue.files(audio_only = True):
+ for file in cue.files():
name = cue.dir + file.name
printf("FILE %s", quote(file.name))
@@ -91,7 +92,7 @@ def print_cue(cue):
info.sample_rate,
info.channels)
- for track in file.tracks(audio_only = True):
+ for track in file.tracks():
printf("\tTRACK %02d", track.number)
title = track.get("title")
if title != "":
@@ -112,8 +113,9 @@ def parse_args():
help="ignore cue parsing errors")
parser.add_option("--dump",
- action="store_true", default=False, dest="dump",
- help="print the content of cue file")
+ dest="dump", choices=["cue", "tags", "tracks"],
+ metavar="cue|tags|tracks",
+ help="print the cue sheet, file tags or track names")
parser.add_option("-n", "--dry-run",
action="store_true", default=False, dest="dry_run")
@@ -143,12 +145,11 @@ def parse_args():
parser.add_option_group(format)
tag = OptionGroup(parser, "Tag options")
+ tag_options = ["album", "artist", "date", "genre",
+ "comment", "composer", "albumartist"]
- tag.add_option("--album", dest="album")
- tag.add_option("--artist", dest="artist")
- tag.add_option("--date", dest="date")
- tag.add_option("--genre", dest="genre")
- tag.add_option("--comment", dest="comment")
+ for opt in tag_options:
+ tag.add_option("--" + opt, dest=opt, default="")
parser.add_option_group(tag)
@@ -224,15 +225,18 @@ class CueSplitter:
self.cue = cue
self.opt = opt
self.tracknumber = 0
- self.tracktotal = sum(
- [len(list(f.tracks(True))) for f in self.cue.files(True)]
- )
+ self.tracktotal = len(list(self.all_tracks()))
self.tags = {
"album": self.opt.album or self.cue.get("title"),
"date": self.opt.date or self.cue.get("date"),
"genre": self.opt.genre or self.cue.get("genre"),
- "comment": self.opt.comment or self.cue.get("comment")
+ "comment": self.opt.comment or self.cue.get("comment"),
+ "composer": self.opt.composer
+ or self.cue.get("songwriter"),
+ "artist": self.opt.albumartist or self.opt.artist
+ or self.cue.get("artist"),
+ "albumartist": self.opt.albumartist
}
def find_realfile(self, name):
@@ -250,7 +254,7 @@ class CueSplitter:
def open_files(self):
lst = []
- for file in self.cue.files(True):
+ for file in self.cue.files():
if not file.has_audio_tracks():
debug("skip file %s: no tracks", quote(file.name))
continue
@@ -281,22 +285,28 @@ class CueSplitter:
title = track.get("title") or "track"
return "%02d.%s.flac" % (self.tracknumber, title)
- def tag(self, track, path):
- self.tags.update({
- "tracknumber": "%02d" % self.tracknumber,
- "tracktotal": "%02d" % self.tracktotal,
+ def get_track_tags(self, track):
+ tags = dict(self.tags)
+ tags.update({
+ "tracknumber": self.tracknumber,
+ "tracktotal": self.tracktotal,
"title": track.get("title"),
"artist": self.opt.artist or track.get("performer") or self.cue.get("performer"),
+ "composer": self.opt.composer or track.get("songwriter")
})
+ return tags
+
+ def tag(self, track, path):
+ tags = self.get_track_tags(track)
args = ["metaflac", "--remove-all-tags", "--import-tags-from=-", path]
printf("Tag [%s] : ", path)
sys.stdout.flush()
proc = Popen(args, stdin = PIPE)
- for k, v in self.tags.items():
- if v is not None and v != "":
+ for k, v in tags.items():
+ if v is not "":
proc.stdin.write(to_bytes("%s=%s\n" % (k.upper(), v)))
proc.stdin.close()
@@ -318,7 +328,7 @@ class CueSplitter:
if noteq(self.opt.channels, file.info.channels):
return False
- track = list(file.tracks(True))[0]
+ track = list(file.tracks())[0]
trackname = self.get_track_name(track)
dest = os.path.join(self.opt.dir, trackname)
@@ -383,7 +393,7 @@ class CueSplitter:
sys.exit(1)
splitted = filterdir(self.opt.dir, "split-track")
- for track, filename in zip(file.tracks(True), splitted):
+ for track, filename in zip(file.tracks(), splitted):
trackname = self.get_track_name(track)
dest = os.path.join(self.opt.dir, trackname)
@@ -410,6 +420,24 @@ class CueSplitter:
else:
self.split_file(file, points)
+ def all_tracks(self):
+ return chain(*[f.tracks() for f in self.cue.files()])
+
+ def dump_tags(self):
+ for track in self.all_tracks():
+ if self.tracknumber:
+ printf("\n")
+
+ self.tracknumber += 1
+ tags = self.get_track_tags(track)
+ for k, v in sorted(tags.items()):
+ if v is not "":
+ printf("%s=%s\n", k.upper(), v)
+ def dump_tracks(self):
+ for track in self.all_tracks():
+ trackname = self.get_track_name(track)
+ printf("%s\n", os.path.join(self.opt.dir, trackname))
+
def main():
options, args = parse_args()
verify_options(options)
@@ -439,10 +467,12 @@ def main():
if cue.dir:
cue.dir += "/"
- if options.dump:
- print_cue(cue)
- else:
- CueSplitter(cue, options).split()
+ {
+ "cue": lambda: print_cue(cue),
+ "tags": lambda: CueSplitter(cue, options).dump_tags(),
+ "tracks": lambda: CueSplitter(cue, options).dump_tracks(),
+ None: lambda: CueSplitter(cue, options).split()
+ }[options.dump]()
return 0