summaryrefslogtreecommitdiff
path: root/debian/patches
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches')
-rw-r--r--debian/patches/05_she_bang.patch13
-rw-r--r--debian/patches/06_link_ncursew.patch17
-rw-r--r--debian/patches/10_vbr_default_man.patch13
-rw-r--r--debian/patches/11_choose_bitrate_quality.patch20
-rw-r--r--debian/patches/12_gogo_vbr-otf-cmd.patch15
-rw-r--r--debian/patches/13_rc_hash.patch91
-rw-r--r--debian/patches/14_tocfile_abspath.patch33
-rw-r--r--debian/patches/15_imagefile_abspath.patch17
-rw-r--r--debian/patches/16_len_unusable_replacement.patch23
-rw-r--r--debian/patches/17_fix_ref_no_various.patch34
-rw-r--r--debian/patches/18_warn_no_base_dir.patch33
-rw-r--r--debian/patches/19_man_duplicate_overwrite.patch16
-rw-r--r--debian/patches/20_fix_sub_paths_warning.patch16
-rw-r--r--debian/patches/21_fallback_ripper.patch62
-rw-r--r--debian/patches/22_msf_offset.patch21
-rw-r--r--debian/patches/23_flac_options.patch17
-rw-r--r--debian/patches/24_vbr_before_otf.patch26
-rw-r--r--debian/patches/25_ignore_empty_freedb_info.patch115
-rw-r--r--debian/patches/26_t_artist_cleanup.patch66
-rw-r--r--debian/patches/27_allow_year_genre_sa.patch13
-rw-r--r--debian/patches/28_allow_edit_cddb.patch34
-rw-r--r--debian/patches/29_remove_freedb-de.patch18
-rw-r--r--debian/patches/30_add_freedb_mirrors.patch84
-rw-r--r--debian/patches/31_real_bitrate_progress.patch26
-rw-r--r--debian/patches/32_man_minus.patch84
-rw-r--r--debian/patches/33_flac_mutagen.patch69
-rw-r--r--debian/patches/34_toc_invocation_fail.patch24
-rw-r--r--debian/patches/35_fix_xtermset.patch14
-rw-r--r--debian/patches/36_check_plugin.patch21
-rw-r--r--debian/patches/37_expand_CBR_acronym.patch15
-rw-r--r--debian/patches/38_remove_gen_device.patch104
-rw-r--r--debian/patches/39_main_loop_valueerror.patch49
-rw-r--r--debian/patches/40_enable_term.patch55
-rw-r--r--debian/patches/41_nicify_wait.patch24
-rw-r--r--debian/patches/42_cd_device_fallback.patch56
-rw-r--r--debian/patches/43_string_option.patch22
-rw-r--r--debian/patches/44_guess_toc_ogg_flac.patch89
-rw-r--r--debian/patches/45_fix_normalize_example.patch16
-rw-r--r--debian/patches/46_case_insens_fn.dpatch33
-rw-r--r--debian/patches/47_locale_check.patch26
-rw-r--r--debian/patches/48_search_base_dir.patch21
-rw-r--r--debian/patches/49_nicer_ripper_encoder.patch32
-rw-r--r--debian/patches/50_check_ripper_encoder.patch34
-rw-r--r--debian/patches/51_error_not_block_device.patch36
-rw-r--r--debian/patches/52_cdparanoia_toc.patch69
-rw-r--r--debian/patches/53_no_tag_when_freedb_fails.patch38
-rw-r--r--debian/patches/54_check_cont_failed_query.patch19
-rw-r--r--debian/patches/55_fix_sloppy.patch25
-rw-r--r--debian/patches/56_ctrl_c_termset.patch71
-rw-r--r--debian/patches/57_feedb_asciiletters.patch18
-rw-r--r--debian/patches/58_progress_changed_error.patch14
-rw-r--r--debian/patches/59_assume_ok_query.patch33
-rw-r--r--debian/patches/60_ask_edit_freedb_when_query_fails.patch19
-rw-r--r--debian/patches/61_pymem_del.patch27
-rw-r--r--debian/patches/62_dont_repeat_inexact.patch39
-rw-r--r--debian/patches/63_date_unicode.patch14
-rw-r--r--debian/patches/64_catch_id3_error.patch29
-rw-r--r--debian/patches/66_rename_unicode.patch19
-rw-r--r--debian/patches/67_progress_utf8_vs_filenames.patch16
-rw-r--r--debian/patches/68_support_high_char_renames.patch21
-rw-r--r--debian/patches/69_document_freedb_dir.patch19
-rw-r--r--debian/patches/70_fix_upd_progress.patch76
-rw-r--r--debian/patches/71_freedb_filename_cleanup.patch90
-rw-r--r--debian/patches/72_upd_progress_renamed.patch72
-rw-r--r--debian/patches/73_err_unknown_sub.patch98
-rw-r--r--debian/patches/74_multi_replace_cleanup.patch94
-rw-r--r--debian/patches/75_fix_datatrack_rename.patch177
-rw-r--r--debian/patches/76_mkdirname_cleanup.patch40
-rw-r--r--debian/patches/77_upd_progress_flac.patch32
-rw-r--r--debian/patches/78_setlocale.patch16
-rw-r--r--debian/patches/79_unicode_width.patch52
-rw-r--r--debian/patches/80_dest_exists_abs_path.patch16
-rw-r--r--debian/patches/81_check_space.patch30
-rw-r--r--debian/patches/82_fix_append_year_doc.patch31
-rw-r--r--debian/patches/83_man_plugin.patch53
-rw-r--r--debian/patches/84_dyear_dgenre.patch107
-rw-r--r--debian/patches/85_dir_template_yg.patch54
-rw-r--r--debian/patches/86_mention_year_dir_template.patch14
-rw-r--r--debian/patches/87_use_existing_cddb_category.patch121
-rw-r--r--debian/patches/88_fix_argv_loop.patch27
-rw-r--r--debian/patches/89_saner_argv_lists.patch35
-rw-r--r--debian/patches/90_fix_df.patch24
-rw-r--r--debian/patches/91_fix_cdrdao_image.patch34
-rw-r--r--debian/patches/92_fix_python2.6_warning.patch21
-rw-r--r--debian/patches/93_extd_parsing.patch44
-rw-r--r--debian/patches/94_addstr_error.patch40
-rw-r--r--debian/patches/95_fix_empty_input.patch42
-rw-r--r--debian/patches/96_fix_cdda2wav_parsing.patch33
-rw-r--r--debian/patches/97_man_mp3vsogg.patch90
-rw-r--r--debian/patches/98_man_default_encoders.patch13
-rw-r--r--debian/patches/99_addstr_error.patch43
-rw-r--r--debian/patches/99a_correct-category-list.patch54
92 files changed, 3810 insertions, 0 deletions
diff --git a/debian/patches/05_she_bang.patch b/debian/patches/05_she_bang.patch
new file mode 100644
index 0000000..f79b798
--- /dev/null
+++ b/debian/patches/05_she_bang.patch
@@ -0,0 +1,13 @@
+Debian-specific; in fact, probably a bad idea. Michael, why did you put
+this in? Right, so Michael pointed me at Debian #148415. I'll have to
+review the arguments at some point.
+
+diff -urN jack-2.99.9/jack jack-2.99.9.new/jack
+--- jack-2.99.9/jack Tue Jun 25 01:16:28 2002
++++ jack-2.99.9.new/jack Tue Jun 25 01:15:33 2002
+@@ -1,4 +1,4 @@
+-#!/usr/bin/env python
++#!/usr/bin/python
+ ### jack - extract audio from a CD and encode it using 3rd party software
+ ### Copyright (C) 1999-2003 Arne Zellentin <zarne@users.sf.net>
+
diff --git a/debian/patches/06_link_ncursew.patch b/debian/patches/06_link_ncursew.patch
new file mode 100644
index 0000000..353aea5
--- /dev/null
+++ b/debian/patches/06_link_ncursew.patch
@@ -0,0 +1,17 @@
+Link against ncursesw rather than ncurses so UTF-8 will work
+properly. See http://bugs.debian.org/337328 for a discussion
+of this.
+
+--- setup.py~ 2007-10-21 14:51:07.000000000 +0200
++++ setup.py 2007-10-21 14:51:42.000000000 +0200
+@@ -14,7 +14,8 @@
+
+ # Description of the modules and packages in the distribution
+ ext_modules = [ Extension('jack_cursesmodule',
+- ['cursesmodule/jack_cursesmodule.c'], libraries=["ncurses"],
++ ['cursesmodule/jack_cursesmodule.c'], libraries=["ncursesw"],
++ include_dirs=["/usr/include/ncursesw"],
+ extra_compile_args=["-Wno-strict-prototypes"]) ],
+
+ py_modules = [ 'jack_CDTime', 'jack_TOC', 'jack_TOCentry', 'jack_argv',
+
diff --git a/debian/patches/10_vbr_default_man.patch b/debian/patches/10_vbr_default_man.patch
new file mode 100644
index 0000000..aa5a46f
--- /dev/null
+++ b/debian/patches/10_vbr_default_man.patch
@@ -0,0 +1,13 @@
+The default of --vbr has been "yes" for a while.
+
+--- a/jack.man~ 2005-11-09 22:06:43.000000000 +0000
++++ b/jack.man 2004-12-12 04:54:35.000000000 +0000
+@@ -391,7 +391,7 @@
+ .TP
+ .B \-v, \-\-vbr=bool
+ Generate variable bitrate files, only on encoders which support
+-this. Default is no.
++this. Default is yes.
+ .TP
+ .B \-\-various=bool
+ when parsing freedb data, Jack assumes that if the disc\'s artist
diff --git a/debian/patches/11_choose_bitrate_quality.patch b/debian/patches/11_choose_bitrate_quality.patch
new file mode 100644
index 0000000..2dadbdb
--- /dev/null
+++ b/debian/patches/11_choose_bitrate_quality.patch
@@ -0,0 +1,20 @@
+Use fixed bitrate when a bitrate is given on the command line even when the
+config defaults to variable bitrate. Debian #293334.
+
+--- a/jack_checkopts.py~ 2005-11-09 22:40:49.000000000 +0000
++++ b/jack_checkopts.py 2005-11-09 23:03:19.000000000 +0000
+@@ -65,6 +65,14 @@
+ cf.rupdate({'id3_genre': {'val': genre}}, "check")
+ del genre
+
++ if not cf2.has_key('vbr'):
++ if cf2.has_key('bitrate') and cf2.has_key('vbr_quality'):
++ cf.rupdate({'vbr': {'val': 1}}, "check")
++ elif cf2.has_key('bitrate'):
++ cf.rupdate({'vbr': {'val': 0}}, "check")
++ elif cf2.has_key('vbr_quality'):
++ cf.rupdate({'vbr': {'val': 1}}, "check")
++
+ for i in cf2.keys():
+ if not cf.has_key(i):
+ error("unknown config item `%s'" % i)
diff --git a/debian/patches/12_gogo_vbr-otf-cmd.patch b/debian/patches/12_gogo_vbr-otf-cmd.patch
new file mode 100644
index 0000000..11f759d
--- /dev/null
+++ b/debian/patches/12_gogo_vbr-otf-cmd.patch
@@ -0,0 +1,15 @@
+Fix gogo's vbr-otf-cmd to use the quality variable rather than a hardcoded
+value.
+
+diff -urN jack-3.1.1~/jack_helpers.py jack-3.1.1/jack_helpers.py
+--- jack-3.1.1~/jack_helpers.py 2005-11-11 17:22:46.000000000 +0000
++++ jack-3.1.1/jack_helpers.py 2005-11-11 17:23:11.000000000 +0000
+@@ -145,7 +145,7 @@
+ 'cmd': "gogo %i %o -b %r",
+ 'vbr-cmd': "gogo %i %o -v %q",
+ 'otf-cmd': "gogo stdin %o -b %r",
+- 'vbr-otf-cmd': "gogo stdin %o -v 4",
++ 'vbr-otf-cmd': "gogo stdin %o -v %q",
+ 'status_blocksize': 160,
+ 'bitrate_factor': 1,
+ 'status_start': "%",
diff --git a/debian/patches/13_rc_hash.patch b/debian/patches/13_rc_hash.patch
new file mode 100644
index 0000000..d936f12
--- /dev/null
+++ b/debian/patches/13_rc_hash.patch
@@ -0,0 +1,91 @@
+Don't automatically assume that a hash (#) in the configuration file is a
+comment since it can also occur in the value of config variables. Debian:
+#338621.
+
+diff -urN jack-3.1.1~/jack_rc.py jack-3.1.1/jack_rc.py
+--- jack-3.1.1~/jack_rc.py 2005-11-11 17:48:44.000000000 +0000
++++ jack-3.1.1/jack_rc.py 2005-11-11 17:48:54.000000000 +0000
+@@ -32,39 +32,45 @@
+
+ def read(file):
+ read_rc = []
+-
+ try:
+ f = open(file)
+- except:
++ except (IOError, OSError):
+ return read_rc
+-
+ lineno = 0
+- while 1:
+- x = f.readline()
+- if not x:
+- break
++ for x in f.readlines():
++ lineno += 1
++ x = x.strip()
+ opt = val = com = None
+- lineno = lineno + 1
+-
+- x = string.strip(x)
+- x = string.split(x, "#", 1)
+- if len(x) > 1:
+- opt, com = x
++ if not x:
++ # also return empty lines so --save will honour them
++ pass
++ elif x.startswith("#"):
++ com = x[1:]
+ else:
+- opt = x[0]
+- if opt and com:
+- opt = string.strip(opt)
+- if opt:
+- x = string.split(opt, ":", 1)
+- if len(x) > 1:
+- opt, val = x
+- else:
++ x = [i.strip() for i in x.split(":", 1)]
++ if len(x) < 2:
+ opt = x[0]
+- else:
+- opt = None
++ else:
++ opt, val = x
++ # check if there's a comment ridden in val
++ if "#" in val:
++ quoted = []
++ for i in range(len(val)):
++ c = val[i]
++ if c in ('"', "'") and (not i or val[i-1] != "\\"):
++ if quoted and quoted[-1] == c:
++ quoted.pop()
++ else:
++ quoted.append(c)
++ elif c == "#" and not quoted:
++ val, com = val[:i].strip(), val[i+1:]
++ print com
++ break
+ read_rc.append([opt, val, com, lineno])
+ version = get_version(read_rc)
+- if version != jack_version.prog_rcversion:
++ if not version:
++ warning("config file %s doesn't define jackrc-version." % file)
++ elif version != jack_version.prog_rcversion:
+ warning("config file %s is of unknown version %s." % (file, `version`))
+ return read_rc
+
+@@ -80,10 +86,9 @@
+ return None
+ if vers[0] != "jackrc-version":
+ return None
+- ver = int(vers[1])
+- return ver
+- else:
+- return None
++ if vers[1].isdigit():
++ return int(vers[1])
++ return None
+
+ def load(cf, file):
+ rc = read(expand(file))
diff --git a/debian/patches/14_tocfile_abspath.patch b/debian/patches/14_tocfile_abspath.patch
new file mode 100644
index 0000000..cdff8b4
--- /dev/null
+++ b/debian/patches/14_tocfile_abspath.patch
@@ -0,0 +1,33 @@
+Print a better warning when the cdrdao toc file cannot be found, and use
+the absolute path so the file will be found if it exists. Debian #338697.
+
+
+diff -urN jack-3.1.1~/jack_functions.py jack-3.1.1/jack_functions.py
+--- jack-3.1.1~/jack_functions.py 2005-11-12 12:16:08.000000000 +0000
++++ jack-3.1.1/jack_functions.py 2005-11-12 12:16:20.000000000 +0000
+@@ -236,7 +236,12 @@
+ "returns TOC object, needs name of toc-file to read"
+ toc = jack_TOC.TOC()
+
+- f = open(tocfile, "r")
++ if not os.path.exists(tocfile):
++ error("Can't open TOC file '%s': file does not exist." % os.path.abspath(tocfile))
++ try:
++ f = open(tocfile, "r")
++ except (IOError, OSError), e:
++ error("Can't open TOC file '%s': %s" % (os.path.abspath(tocfile), e))
+
+ tocpath, tocfiledummy = os.path.split(tocfile)
+
+diff -urN jack-3.1.1~/jack_prepare.py jack-3.1.1/jack_prepare.py
+--- jack-3.1.1~/jack_prepare.py 2005-11-12 12:16:08.000000000 +0000
++++ jack-3.1.1/jack_prepare.py 2005-11-12 16:48:29.000000000 +0000
+@@ -58,6 +58,8 @@
+ jack_ripstuff.all_tracks = []
+ else:
+ if cf['_image_toc_file']:
++ # put the absolute path in the variable since we'll change cwd soon
++ cf['_image_toc_file'] = os.path.abspath(cf['_image_toc_file'])
+ jack_ripstuff.all_tracks, dummy, dummy = jack_functions.cdrdao_gettoc(cf['_image_toc_file'])
+ else:
+ jack_ripstuff.all_tracks = jack_functions.gettoc(cf['_toc_prog'])
diff --git a/debian/patches/15_imagefile_abspath.patch b/debian/patches/15_imagefile_abspath.patch
new file mode 100644
index 0000000..58253f3
--- /dev/null
+++ b/debian/patches/15_imagefile_abspath.patch
@@ -0,0 +1,17 @@
+If an image file is specified without a toc file, print a warning that the
+TOC will be obtained from the CD; also use the absolute path of the image
+file since we're about to change cwd. Debian #338697.
+
+diff -urN jack-3.1.1~/jack_prepare.py jack-3.1.1/jack_prepare.py
+--- jack-3.1.1~/jack_prepare.py 2005-11-12 18:54:42.000000000 +0000
++++ jack-3.1.1/jack_prepare.py 2005-11-12 18:55:28.000000000 +0000
+@@ -62,6 +62,9 @@
+ cf['_image_toc_file'] = os.path.abspath(cf['_image_toc_file'])
+ jack_ripstuff.all_tracks, dummy, dummy = jack_functions.cdrdao_gettoc(cf['_image_toc_file'])
+ else:
++ if cf['_image_file']:
++ warning("No TOC file for image '%s' specified, reading TOC from CD device." % cf['_image_file'])
++ cf['_image_file'] = os.path.abspath(cf['_image_file'])
+ jack_ripstuff.all_tracks = jack_functions.gettoc(cf['_toc_prog'])
+ toc_just_read = 1
+ # check that the generic device is usable, too
diff --git a/debian/patches/16_len_unusable_replacement.patch b/debian/patches/16_len_unusable_replacement.patch
new file mode 100644
index 0000000..74ad7b8
--- /dev/null
+++ b/debian/patches/16_len_unusable_replacement.patch
@@ -0,0 +1,23 @@
+Print a warning if the number of elements of replacement_chars and
+unusable_chars is different.
+
+--- a/jack_checkopts.py~ 2005-12-01 10:50:25.000000000 +0000
++++ b/jack_checkopts.py 2005-12-01 10:53:54.000000000 +0000
+@@ -135,6 +135,7 @@
+
+ # stretch replacement_chars
+ if len(cf['_unusable_chars']) > len(cf['_replacement_chars']):
++ warning("unusable_chars contains more elements than replacement_chars")
+ u, r = cf['_unusable_chars'], cf['_replacement_chars']
+ while len(u) > len(r):
+ if type(r) == types.ListType:
+@@ -145,6 +146,9 @@
+ error("unsupported type: " + `type(cf['replacement_chars']['val'][-1])`)
+ cf.rupdate({'replacement_chars': {'val': r}}, "check")
+ del u, r
++ elif len(cf['_replacement_chars']) > len(cf['_unusable_chars']):
++ # This has no practical negative effect but print a warning anyway
++ warning("replacement_chars contains more elements than unusable_chars")
+
+ if cf['silent_mode']['val']:
+ cf['terminal']['val'] = "dumb"
diff --git a/debian/patches/17_fix_ref_no_various.patch b/debian/patches/17_fix_ref_no_various.patch
new file mode 100644
index 0000000..7f757eb
--- /dev/null
+++ b/debian/patches/17_fix_ref_no_various.patch
@@ -0,0 +1,34 @@
+Change references from the removed --no-various option to --various=no.
+Debian #345367.
+
+diff -urN jack-3.1.1~/doc/usage.html jack-3.1.1/doc/usage.html
+--- jack-3.1.1~/doc/usage.html 2005-12-31 15:04:05.000000000 +0100
++++ jack-3.1.1/doc/usage.html 2005-12-31 15:07:45.000000000 +0100
+@@ -194,12 +194,9 @@
+ <TD>when parsing freedb data, jack assumes that if the disc's
+ artist is set to "Various Artists" the track titles have the format "[artist] -
+ [title]". If the disc title is set to something else and you still want above
+-behaviour, use --various.
+-</TR>
+-
+-<TR><TD>--no-various
+-<TD>use this if freedb data says it't "Various Artists" but you want the normal
+-renaming scheme, e.g. if Jack can't seperate artist and track title.
++behaviour, use --various. You can use --various=no if the FreeDB data says
++"Various Artists" but you want the normal renaming scheme, e.g. if Jack
++can't seperate artist and track title.
+ </TR>
+
+ <TR><TD>--remove
+diff -urN jack-3.1.1~/jack_freedb.py jack-3.1.1/jack_freedb.py
+--- jack-3.1.1~/jack_freedb.py 2005-12-31 15:04:05.000000000 +0100
++++ jack-3.1.1/jack_freedb.py 2005-12-31 15:06:32.000000000 +0100
+@@ -577,7 +577,7 @@
+ else:
+ err = 7
+ if verb:
+- warning("could not separate artist and title in all TTITLEs. Try setting freedb_pedantic = 0 or use --no-various Maybe additional information is contained in the EXTT fields. check %s and use either --extt-is-artist or --extt-is-title." % cf['_freedb_form_file'])
++ warning("could not separate artist and title in all TTITLEs. Try setting freedb_pedantic = 0 or use --various=no. Maybe additional information is contained in the EXTT fields. check %s and use either --extt-is-artist or --extt-is-title." % cf['_freedb_form_file'])
+ else:
+ for i in range(tracks_on_cd):
+ buf = freedb['TTITLE'+`i`]
diff --git a/debian/patches/18_warn_no_base_dir.patch b/debian/patches/18_warn_no_base_dir.patch
new file mode 100644
index 0000000..418b508
--- /dev/null
+++ b/debian/patches/18_warn_no_base_dir.patch
@@ -0,0 +1,33 @@
+Add a warning if base_dir is not set. Maybe Debian-specific, but I think
+it doesn't hurt it put this in upstream. Also, we definitely need this
+check_rc function for a later patch.
+
+
+diff -urN jack-3.1.1~/jack jack-3.1.1/jack
+--- jack-3.1.1~/jack 2006-01-11 13:31:39.000000000 +0000
++++ jack-3.1.1/jack 2006-01-11 13:48:44.000000000 +0000
+@@ -84,6 +84,7 @@
+ debug("user_cf: " + `user_cf`)
+ debug("argv_cf: " + `argv_cf`)
+
++jack_checkopts.check_rc(global_cf, user_cf, argv_cf)
+ jack_checkopts.consistency_check(cf)
+
+ if cf['save_args']['val'] == 1:
+diff -urN jack-3.1.1~/jack_checkopts.py jack-3.1.1/jack_checkopts.py
+--- jack-3.1.1~/jack_checkopts.py 2006-01-11 13:31:39.000000000 +0000
++++ jack-3.1.1/jack_checkopts.py 2006-01-11 13:48:23.000000000 +0000
+@@ -215,3 +215,13 @@
+
+ if cf['_dont_work'] and cf['_query_when_ready']:
+ warning("you want to use --query-now / -Q instead of --query / -q")
++
++# Checks concerning options specified by the user (in the global or user rc
++# files or the command line), i.e. options/values that are not the default
++# jack options from jack_config.
++def check_rc(global_cf, user_cf, argv_cf):
++
++ all_keys = global_cf.keys() + user_cf.keys() + argv_cf.keys()
++ if 'base_dir' not in all_keys:
++ warning("You have no standard location set, putting files into the current directory. Please consider setting base_dir in ~/.jack3rc.")
++
diff --git a/debian/patches/19_man_duplicate_overwrite.patch b/debian/patches/19_man_duplicate_overwrite.patch
new file mode 100644
index 0000000..0c03938
--- /dev/null
+++ b/debian/patches/19_man_duplicate_overwrite.patch
@@ -0,0 +1,16 @@
+Don't list the --overwrite option twice in the man page. Debian #347975.
+
+
+diff -urN jack-3.1.1~/jack.man jack-3.1.1/jack.man
+--- jack-3.1.1~/jack.man 2006-01-16 23:02:45.000000000 +0000
++++ jack-3.1.1/jack.man 2006-01-16 23:03:44.000000000 +0000
+@@ -256,9 +256,6 @@
+ On-the-fly operation. Only on some encoders/rippers. Do not
+ create WAVs, pipe ripper output through the encoder. Default is
+ no as it's a torture for the CDROM drive.
+-.TP
+-.B \-o, \-\-overwrite=bool
+-overwrite existing files.
+ .\" .TP
+ .\" .B \-\-playorder
+ .\" use the FreeDB PLAYORDER field to limit the tracks to
diff --git a/debian/patches/20_fix_sub_paths_warning.patch b/debian/patches/20_fix_sub_paths_warning.patch
new file mode 100644
index 0000000..a645399
--- /dev/null
+++ b/debian/patches/20_fix_sub_paths_warning.patch
@@ -0,0 +1,16 @@
+Update the variable after, not before, printing the warning, otherwise the
+warning is bogus ("dir-template consists of more sub-paths (3) than
+scan-dirs (3)", doh). Also fix s/he/it/ - jack is not a person.
+
+--- a/jack_checkopts.py~ 2006-01-23 14:39:36.000000000 +0000
++++ b/jack_checkopts.py 2006-01-23 14:40:50.000000000 +0000
+@@ -90,8 +90,8 @@
+
+ # check dir_template and scan_dirs
+ if len(cf['_dir_template'].split(os.path.sep)) > cf['_scan_dirs']:
++ warning("dir-template consists of more sub-paths (%i) than scan-dirs (%i). Jack may not find the workdir next time it is run. (Auto-raised)" % (len(cf['_dir_template'].split(os.path.sep)), cf['_scan_dirs']))
+ cf.rupdate({'scan_dirs': {'val': len(cf['_dir_template'].split(os.path.sep))}}, "check")
+- warning("dir-template consists of more sub-paths (%i) than scan-dirs (%i). Jack may not find the workdir next time he is run. (Auto-raised)" % (len(cf['_dir_template'].split(os.path.sep)), cf['_scan_dirs']))
+
+ # check for unsername
+ if cf['username']['val'] == None:
diff --git a/debian/patches/21_fallback_ripper.patch b/debian/patches/21_fallback_ripper.patch
new file mode 100644
index 0000000..31e21fd
--- /dev/null
+++ b/debian/patches/21_fallback_ripper.patch
@@ -0,0 +1,62 @@
+Fallback to an installed ripper when the default one is not available and
+the user has not specified one. Debian #347975.
+
+Depends on 18_warn_no_base_dir.patch for check_rc().
+
+diff -urN jack-3.1.1~/jack jack-3.1.1/jack
+--- jack-3.1.1~/jack 2006-01-23 23:40:49.000000000 +0000
++++ jack-3.1.1/jack 2006-01-23 23:41:52.000000000 +0000
+@@ -84,7 +84,7 @@
+ debug("user_cf: " + `user_cf`)
+ debug("argv_cf: " + `argv_cf`)
+
+-jack_checkopts.check_rc(global_cf, user_cf, argv_cf)
++jack_checkopts.check_rc(cf, global_cf, user_cf, argv_cf)
+ jack_checkopts.consistency_check(cf)
+
+ if cf['save_args']['val'] == 1:
+diff -urN jack-3.1.1~/jack_checkopts.py jack-3.1.1/jack_checkopts.py
+--- jack-3.1.1~/jack_checkopts.py 2006-01-23 23:40:49.000000000 +0000
++++ jack-3.1.1/jack_checkopts.py 2006-01-24 00:04:35.000000000 +0000
+@@ -219,9 +219,22 @@
+ # Checks concerning options specified by the user (in the global or user rc
+ # files or the command line), i.e. options/values that are not the default
+ # jack options from jack_config.
+-def check_rc(global_cf, user_cf, argv_cf):
++def check_rc(cf, global_cf, user_cf, argv_cf):
+
+ all_keys = global_cf.keys() + user_cf.keys() + argv_cf.keys()
+ if 'base_dir' not in all_keys:
+ warning("You have no standard location set, putting files into the current directory. Please consider setting base_dir in ~/.jack3rc.")
+
++ # Check if the default ripper is installed, and if not, look for another one
++ if 'ripper' not in all_keys:
++ default_ripper = cf["ripper"]["val"]
++ if not jack_utils.in_path(default_ripper):
++ rippers = [i for i in jack_helpers.helpers if jack_helpers.helpers[i]["type"] == "ripper" and jack_helpers.helpers[i].has_key("toc_cmd")]
++ for cmd in rippers:
++ if jack_utils.in_path(cmd):
++ warning("Using ripper %s since default ripper %s is not available." % (cmd, default_ripper))
++ cf.rupdate({'ripper': {'val': cmd}}, "check")
++ break
++ else:
++ error("No valid ripper found on your system.")
++
+diff -urN jack-3.1.1~/jack_utils.py jack-3.1.1/jack_utils.py
+--- jack-3.1.1~/jack_utils.py 2006-01-23 23:40:49.000000000 +0000
++++ jack-3.1.1/jack_utils.py 2006-01-24 00:04:35.000000000 +0000
+@@ -207,6 +207,13 @@
+ new_path.append(base)
+ new_path.reverse()
+
++def in_path(file):
++ "check if a file is an executable in PATH"
++ for path in os.environ.get("PATH", "").split(os.path.pathsep):
++ p = os.path.join(path, file)
++ if (os.path.isfile(p) and os.access(p, os.X_OK)): return True
++ return False
++
+ def ex_edit(file):
+ editor = "/usr/bin/sensible-editor"
+ if os.environ.has_key("EDITOR"):
+
diff --git a/debian/patches/22_msf_offset.patch b/debian/patches/22_msf_offset.patch
new file mode 100644
index 0000000..b7bcb2c
--- /dev/null
+++ b/debian/patches/22_msf_offset.patch
@@ -0,0 +1,21 @@
+Don't assume that the first song starts right after the MSF offset. This
+fixes the FreeDB (CDDB) ID calculation which was broken with some CDs.
+Debian #319901.
+
+This patch indirectly also causes jack to use the tracksize information
+from cdparanoia which is more accurate and therefore won't lead to failures
+on tracks right before a data track. Debian #319894.
+
+
+diff -urN jack-3.1.1.orig/jack_helpers.py jack-3.1.1/jack_helpers.py
+--- jack-3.1.1.orig/jack_helpers.py 2005-07-26 20:10:09.231433216 +0100
++++ jack-3.1.1/jack_helpers.py 2005-07-26 20:10:28.655480312 +0100
+@@ -488,7 +488,7 @@
+ device.close()
+ toc.append(min * 60 * 75 + sec * 75 + frame)
+ for i in range(first, last + 1):
+- erg.append([i, toc[i - first + 1] - toc[i - first], toc[i - first] - toc[0], 0, 0, 2, 1, cf['_bitrate'], cf['_name'] % i])
++ erg.append([i, toc[i - first + 1] - toc[i - first], toc[i - first] - MSF_OFFSET, 0, 0, 2, 1, cf['_bitrate'], cf['_name'] % i])
+ """,
+ }
+ }
diff --git a/debian/patches/23_flac_options.patch b/debian/patches/23_flac_options.patch
new file mode 100644
index 0000000..8caf54e
--- /dev/null
+++ b/debian/patches/23_flac_options.patch
@@ -0,0 +1,17 @@
+Update options passed to the FLAC encoder; thanks, Robert Millan.
+Debian #319950.
+
+diff -urN a/jack_helpers.py jack-3.1.1+cvs20050801/jack_helpers.py
+--- a/jack_helpers.py 2006-02-05 15:54:03.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_helpers.py 2006-02-05 16:08:39.000000000 +0000
+@@ -210,8 +210,8 @@
+ 'flac': {
+ 'type': "encoder",
+ 'target': "flac",
+- 'vbr-cmd': "flac -o %o %i",
+- 'vbr-otf-cmd': "flac -fr -fb -fc 2 -fp 16 -fs 44100 -o %o",
++ 'vbr-cmd': "flac -o %o %i",
++ 'vbr-otf-cmd': "flac --channels 2 --bps 16 --sample-rate 44100 --force-raw-format --endian=big --sign=signed -o %o -",
+ 'status_blocksize': 160,
+ 'status_start': "%",
+ 'percent_fkt': r"""
diff --git a/debian/patches/24_vbr_before_otf.patch b/debian/patches/24_vbr_before_otf.patch
new file mode 100644
index 0000000..07a5eb8
--- /dev/null
+++ b/debian/patches/24_vbr_before_otf.patch
@@ -0,0 +1,26 @@
+Check for the availability of VBR before OTF so it's possible to fall back
+to fixed bitrate OTF encoding; thanks, Robert Millan. Debia: #320093.
+
+diff -urN jack-3.1.1~/jack_checkopts.py jack-3.1.1/jack_checkopts.py
+--- jack-3.1.1~/jack_checkopts.py 2005-07-26 23:01:54.740757664 +0100
++++ jack-3.1.1/jack_checkopts.py 2005-07-26 23:06:30.786792288 +0100
+@@ -178,15 +178,15 @@
+ warning("disabling on-the-fly operation as we're reading from image.")
+ cf.rupdate({'otf': {'val': 0}}, "check")
+
++ if cf['_vbr'] and not jack_helpers.helpers[cf['_encoder']].has_key('vbr-cmd'):
++ warning("disabling VBR because " + cf['_encoder'] + " doesn't support it.")
++ cf.rupdate({'vbr': {'val': 0}}, "check")
++
+ if cf['_otf']:
+ for i in (cf['_ripper'], cf['_encoder']):
+ if not jack_helpers.helpers[i].has_key(('vbr-' * cf['_vbr'] * (i == cf['_encoder'])) + 'otf-cmd'):
+ error("can't do on-the-fly because " + jack_helpers.helpers[i]['type'] + " " + i + " doesn't support it.")
+
+- if cf['_vbr'] and not jack_helpers.helpers[cf['_encoder']].has_key('vbr-cmd'):
+- warning("disabling VBR because " + cf['_encoder'] + " doesn't support it.")
+- cf.rupdate({'vbr': {'val': 0}}, "check")
+-
+ if not cf['_vbr'] and not jack_helpers.helpers[cf['_encoder']].has_key('cmd'):
+ error("can't do CBR because " + cf['encoder']['val'] + " doesn't support it. Use -v")
+
diff --git a/debian/patches/25_ignore_empty_freedb_info.patch b/debian/patches/25_ignore_empty_freedb_info.patch
new file mode 100644
index 0000000..c8b8cee
--- /dev/null
+++ b/debian/patches/25_ignore_empty_freedb_info.patch
@@ -0,0 +1,115 @@
+Print a warning but not an error when the FreeDB file has missing track
+information for a track which is not about to be ripped/tagged.
+Debian #292612.
+
+diff -urN a/jack jack-3.1.1+cvs20050801/jack
+--- a/jack 2006-02-05 15:18:38.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack 2006-02-05 15:19:32.000000000 +0000
+@@ -149,12 +149,12 @@
+ if not os.path.exists(cf['_freedb_form_file'] + ".bak"):
+ cf['_query_on_start'] = 1
+ if cf['_query_on_start']:
+- freedb_rename = jack_prepare.query_on_start()
++ freedb_rename = jack_prepare.query_on_start(todo)
+
+ ### (10) update freedb dbfile
+ if cf['_update_freedb']:
+ if not jack_tag.track_names:
+- err, jack_tag.track_names, jack_tag.locale_names, freedb_rename, revision = jack_freedb.interpret_db_file(jack_ripstuff.all_tracks, cf['_freedb_form_file'], verb = 1, dirs = 0)
++ err, jack_tag.track_names, jack_tag.locale_names, freedb_rename, revision = jack_freedb.interpret_db_file(jack_ripstuff.all_tracks, todo, cf['_freedb_form_file'], verb = 1, dirs = 0)
+ jack_freedb.freedb_template(jack_ripstuff.all_tracks, jack_tag.track_names, revision + 1)
+ jack_utils.ex_edit(cf['_freedb_form_file'])
+ info("now submit your changes if you like, using the option --submit (via http POST). Don't forget to activate your changes locally with -R")
+@@ -251,7 +251,7 @@
+ jack_display.exit()
+
+ if cf['_query_when_ready'] or cf['_read_freedb_file'] or cf['_query_on_start']:
+- err, jack_tag.track_names, jack_tag.locale_names, freedb_rename, revision = jack_freedb.interpret_db_file(jack_ripstuff.all_tracks, cf['_freedb_form_file'], verb = 1, dirs = 1)
++ err, jack_tag.track_names, jack_tag.locale_names, freedb_rename, revision = jack_freedb.interpret_db_file(jack_ripstuff.all_tracks, todo, cf['_freedb_form_file'], verb = 1, dirs = 1)
+ if err:
+ error("could not read freedb file")
+
+diff -urN a/jack_freedb.py jack-3.1.1+cvs20050801/jack_freedb.py
+--- a/jack_freedb.py 2006-02-05 15:18:38.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_freedb.py 2006-02-05 15:21:03.000000000 +0000
+@@ -53,14 +53,14 @@
+ },
+ }
+
+-def interpret_db_file(all_tracks, freedb_form_file, verb, dirs = 0, warn = None):
++def interpret_db_file(all_tracks, todo, freedb_form_file, verb, dirs = 0, warn = None):
+ "read freedb file and rename dir(s)"
+ global names_available, dir_created
+ freedb_rename = 0
+ if warn == None:
+- err, track_names, locale_names, cd_id, revision = freedb_names(freedb_id(all_tracks), all_tracks, freedb_form_file, verb = verb)
++ err, track_names, locale_names, cd_id, revision = freedb_names(freedb_id(all_tracks), all_tracks, todo, freedb_form_file, verb = verb)
+ else:
+- err, track_names, locale_names, cd_id, revision = freedb_names(freedb_id(all_tracks), all_tracks, freedb_form_file, verb = verb, warn = warn)
++ err, track_names, locale_names, cd_id, revision = freedb_names(freedb_id(all_tracks), all_tracks, todo, freedb_form_file, verb = verb, warn = warn)
+ if (not err) and dirs:
+ freedb_rename = 1
+
+@@ -319,7 +319,7 @@
+ f.close()
+ return err
+
+-def freedb_names(cd_id, tracks, name, verb = 0, warn = 1):
++def freedb_names(cd_id, tracks, todo, name, verb = 0, warn = 1):
+ "returns err, [(artist, albumname), (track_01-artist, track_01-name), ...], cd_id, revision"
+ err = 0
+ tracks_on_cd = tracks[-1][NUM]
+@@ -355,7 +355,8 @@
+
+ for i in tracks: # check that info is there for all tracks
+ if not freedb.has_key("TTITLE%i" % (i[NUM] - 1)): # -1 because freedb starts at 0
+- err = 1
++ if i[NUM] in [x[NUM] for x in todo]:
++ err = 1
+ if verb:
+ warning("no freedb info for track %02i (\"TTITLE%i\")" % (i[NUM], i[NUM] - 1))
+ freedb["TTITLE%i" % (i[NUM] - 1)] = "[not set]"
+diff -urN a/jack_prepare.py jack-3.1.1+cvs20050801/jack_prepare.py
+--- a/jack_prepare.py 2006-02-05 15:18:38.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_prepare.py 2006-02-05 15:25:16.000000000 +0000
+@@ -107,7 +107,7 @@
+ unique_dirs.append(jack_dirs[i])
+ for i in unique_dirs:
+ jack_ripstuff.all_tracks, dummy, track1_offset = jack_functions.cdrdao_gettoc(os.path.join(i, cf['_toc_file']))
+- err, jack_tag.track_names, jack_tag.locale_names, cd_id, revision = freedb_names(jack_freedb.freedb_id(jack_ripstuff.all_tracks), jack_ripstuff.all_tracks, os.path.join(i, cf['_freedb_form_file']), verb = 0, warn = 0)
++ err, jack_tag.track_names, jack_tag.locale_names, cd_id, revision = freedb_names(jack_freedb.freedb_id(jack_ripstuff.all_tracks), jack_ripstuff.all_tracks, jack_ripstuff.all_tracks, os.path.join(i, cf['_freedb_form_file']), verb = 0, warn = 0)
+ if err or cf['_force']:# this means freedb data is not there yet
+ info("matching dir found: %d" % i)
+ pid = os.fork()
+@@ -466,7 +466,7 @@
+ if not is_submittable:
+ error("can't submit in current state, please fix jack.freedb")
+
+- err, jack_tag.track_names, jack_tag.locale_names, cd_id, revision = jack_freedb.freedb_names(jack_freedb.freedb_id(jack_ripstuff.all_tracks), jack_ripstuff.all_tracks, cf['_freedb_form_file'], verb = 1)
++ err, jack_tag.track_names, jack_tag.locale_names, cd_id, revision = jack_freedb.freedb_names(jack_freedb.freedb_id(jack_ripstuff.all_tracks), jack_ripstuff.all_tracks, jack_ripstuff.all_tracks, cf['_freedb_form_file'], verb = 1)
+ if err:
+ error("invalid freedb file")
+ else:
+@@ -477,7 +477,7 @@
+
+ ### (9) do query on start
+
+-def query_on_start():
++def query_on_start(todo):
+ info("querying...")
+ if jack_freedb.freedb_query(jack_freedb.freedb_id(jack_ripstuff.all_tracks), jack_ripstuff.all_tracks, cf['_freedb_form_file']):
+ if cf['_cont_failed_query']:
+@@ -519,11 +519,11 @@
+ freedb_submit()
+
+ if cf['_query_on_start']:
+- err, jack_tag.track_names, jack_tag.locale_names, freedb_rename, revision = jack_freedb.interpret_db_file(jack_ripstuff.all_tracks, cf['_freedb_form_file'], verb = cf['_query_on_start'], dirs = 1)
++ err, jack_tag.track_names, jack_tag.locale_names, freedb_rename, revision = jack_freedb.interpret_db_file(jack_ripstuff.all_tracks, todo, cf['_freedb_form_file'], verb = cf['_query_on_start'], dirs = 1)
+ if err:
+ error("query on start failed to give a good freedb file, aborting.")
+ else:
+- err, jack_tag.track_names, jack_tag.locale_names, freedb_rename, revision = jack_freedb.interpret_db_file(jack_ripstuff.all_tracks, cf['_freedb_form_file'], verb = cf['_query_on_start'], warn = cf['_query_on_start'])
++ err, jack_tag.track_names, jack_tag.locale_names, freedb_rename, revision = jack_freedb.interpret_db_file(jack_ripstuff.all_tracks, todo, cf['_freedb_form_file'], verb = cf['_query_on_start'], warn = cf['_query_on_start'])
+ return freedb_rename
+
+ def undo_rename(status, todo):
diff --git a/debian/patches/26_t_artist_cleanup.patch b/debian/patches/26_t_artist_cleanup.patch
new file mode 100644
index 0000000..c2b78fb
--- /dev/null
+++ b/debian/patches/26_t_artist_cleanup.patch
@@ -0,0 +1,66 @@
+Code clean-up: test only _once_ whether it's a multi-artist (VA) CD
+(regarding the artist name).
+
+--- a/jack_tag.py 2006-02-05 01:19:49.000000000 +0000
++++ b/jack_tag.py 2006-02-05 01:21:23.000000000 +0000
+@@ -76,7 +76,10 @@
+ sys.stdout.write(".") ; sys.stdout.flush()
+ mp3name = i[NAME] + ext
+ wavname = i[NAME] + ".wav"
+- t_artist = track_names[i[NUM]][0]
++ if track_names[i[NUM]][0]:
++ t_artist = track_names[i[NUM]][0]
++ else:
++ t_artist = a_artist
+ t_name = track_names[i[NUM]][1]
+ t_comm = ""
+ if not cf['_only_dae'] and cf['_set_id3tag']:
+@@ -105,10 +108,7 @@
+ tag.setTitle(t_name)
+ tag.setTrackNum((i[NUM],len(jack_ripstuff.all_tracks_orig)))
+ tag.setTitle(t_name)
+- if t_artist:
+- tag.setArtist(t_artist)
+- else:
+- tag.setArtist(a_artist)
++ tag.setArtist(t_artist)
+ if cf['_id3_genre'] != -1:
+ tag.setGenre("(%d)" % (cf['_id3_genre']))
+ if cf['_id3_year'] != -1:
+@@ -130,10 +130,7 @@
+ tag.setTitle(t_name)
+ tag.setTrackNum((i[NUM],len(jack_ripstuff.all_tracks_orig)))
+ tag.setTitle(t_name)
+- if t_artist:
+- tag.setArtist(t_artist)
+- else:
+- tag.setArtist(a_artist)
++ tag.setArtist(t_artist)
+ if cf['_id3_genre'] != -1:
+ tag.setGenre("(%d)" % (cf['_id3_genre']))
+ if cf['_id3_year'] != -1:
+@@ -162,10 +159,7 @@
+ vc.comments['ALBUM'] = a_title.encode("utf-8")
+ vc.comments['TRACKNUMBER'] = `i[NUM]`
+ vc.comments['TITLE'] = t_name.encode("utf-8")
+- if t_artist:
+- vc.comments['ARTIST'] = t_artist.encode("utf-8")
+- else:
+- vc.comments['ARTIST'] = a_artist.encode("utf-8")
++ vc.comments['ARTIST'] = t_artist.encode("utf-8")
+ if cf['_id3_genre'] != -1:
+ vc.comments['GENRE'] = id3genres[cf['_id3_genre']]
+ if cf['_id3_year'] != -1:
+@@ -183,10 +177,7 @@
+ oggi.add_tag('ALBUM', a_title.encode("utf-8"))
+ oggi.add_tag('TRACKNUMBER', `i[NUM]`)
+ oggi.add_tag('TITLE', t_name.encode("utf-8"))
+- if t_artist:
+- oggi.add_tag('ARTIST', t_artist.encode("utf-8"))
+- else:
+- oggi.add_tag('ARTIST', a_artist.encode("utf-8"))
++ oggi.add_tag('ARTIST', t_artist.encode("utf-8"))
+ if cf['_id3_genre'] != -1:
+ oggi.add_tag('GENRE', id3genres[cf['_id3_genre']])
+ if cf['_id3_year'] != -1:
+
diff --git a/debian/patches/27_allow_year_genre_sa.patch b/debian/patches/27_allow_year_genre_sa.patch
new file mode 100644
index 0000000..bbe0817
--- /dev/null
+++ b/debian/patches/27_allow_year_genre_sa.patch
@@ -0,0 +1,13 @@
+Allow %y and %g in filenames of single-artist tracks. Debian #351465
+
+--- a/jack_tag.py 2006-02-05 01:17:06.000000000 +0000
++++ b/jack_tag.py 2006-02-05 01:18:38.000000000 +0000
+@@ -198,7 +198,7 @@
+ newname = jack_misc.multi_replace(cf['_rename_fmt_va'], replacelist)
+
+ else:
+- replacelist = (("%n", cf['_rename_num'] % i[NUM]), ("%a", a_artist), ("%t", t_name), ("%l", a_title))
++ replacelist = (("%n", cf['_rename_num'] % i[NUM]), ("%a", a_artist), ("%t", t_name), ("%l", a_title), ("%y", `cf['_id3_year']`), ("%g", genretxt))
+ newname = jack_misc.multi_replace(cf['_rename_fmt'], replacelist)
+ exec("newname = newname" + cf['_char_filter'])
+ for char_i in range(len(cf['_unusable_chars'])):
diff --git a/debian/patches/28_allow_edit_cddb.patch b/debian/patches/28_allow_edit_cddb.patch
new file mode 100644
index 0000000..9a49b07
--- /dev/null
+++ b/debian/patches/28_allow_edit_cddb.patch
@@ -0,0 +1,34 @@
+Debian used --edit-cddb for a few months, but upstream changed the option
+to --edit-freedb for consistency. Allow --edit-cddb to continue to work,
+but only for backwards compatibility, i.e. print a warning.
+
+diff -urN a/jack_checkopts.py jack-3.1.1+cvs20050801/jack_checkopts.py
+--- a/jack_checkopts.py 2006-02-05 15:54:03.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_checkopts.py 2006-02-05 17:27:40.000000000 +0000
+@@ -59,6 +59,10 @@
+ if cf2.has_key('freedb_rename') and cf2['freedb_rename']['val']:
+ cf.rupdate({'read_freedb_file': {'val': 1}, 'set_id3tag':{'val': 1}}, "check")
+
++ if cf2.has_key('edit_cddb'):
++ warning("--edit-cddb is obsolete, please use --edit-freedb")
++ cf.rupdate({'edit_freedb': {'val': 1}}, "check")
++
+ if cf2.has_key('id3_genre_txt'):
+ genre = jack_functions.check_genre_txt(cf2['id3_genre_txt']['val'])
+ if genre != cf['_id3_genre']:
+diff -urN a/jack_config.py jack-3.1.1+cvs20050801/jack_config.py
+--- a/jack_config.py 2006-02-05 15:54:03.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_config.py 2006-02-05 17:24:46.000000000 +0000
+@@ -524,6 +524,12 @@
+ 'usage': "continue without freedb data if query fails",
+ 'long': 'AUTO',
+ },
++ 'edit_cddb': {
++ # For backwards compatibility only, use edit_freedb instead!
++ 'type': 'toggle',
++ 'val': 0,
++ 'long': 'AUTO',
++ },
+ 'edit_freedb': {
+ 'type': 'toggle',
+ 'val': 0,
diff --git a/debian/patches/29_remove_freedb-de.patch b/debian/patches/29_remove_freedb-de.patch
new file mode 100644
index 0000000..3eac882
--- /dev/null
+++ b/debian/patches/29_remove_freedb-de.patch
@@ -0,0 +1,18 @@
+db.freedb.org no longer exists. Debian #351719.
+
+diff -urN a/jack_freedb.py jack-3.1.1+cvs20050801/jack_freedb.py
+--- a/jack_freedb.py 2006-02-06 22:35:38.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_freedb.py 2006-02-06 22:45:24.000000000 +0000
+@@ -45,12 +45,6 @@
+ 'mail': "freedb-submit@freedb.org",
+ 'my_mail': "default"
+ },
+- 'freedb-de': {
+- 'host': "de.freedb.org",
+- 'id': prog_name + " " + prog_version,
+- 'mail': "freedb-submit@freedb.org",
+- 'my_mail': "default"
+- },
+ }
+
+ def interpret_db_file(all_tracks, freedb_form_file, verb, dirs = 0, warn = None):
diff --git a/debian/patches/30_add_freedb_mirrors.patch b/debian/patches/30_add_freedb_mirrors.patch
new file mode 100644
index 0000000..a44a9a7
--- /dev/null
+++ b/debian/patches/30_add_freedb_mirrors.patch
@@ -0,0 +1,84 @@
+Update the list of FreeDB mirrors.
+
+Depends on 29_remove_freedb-de.patch
+
+diff -urN c/jack_freedb.py jack-3.1.1+cvs20050801/jack_freedb.py
+--- c/jack_freedb.py 2006-02-07 00:30:07.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_freedb.py 2006-02-07 00:32:57.000000000 +0000
+@@ -42,6 +42,9 @@
+ freedb_inexact_match = -1
+ filenames = []
+
++# Warning: code duplication. Make a function through which information can
++# be requested, and let it fall back to generic information (e.g. my_mail,
++# mail, id) and only require individual entries to have 'host'). FIXME
+ freedb_servers = {
+ 'freedb': {
+ 'host': "freedb.freedb.org",
+@@ -49,6 +52,66 @@
+ 'mail': "freedb-submit@freedb.org",
+ 'my_mail': "default"
+ },
++ 'freedb-at': {
++ 'host': "at.freedb.org",
++ 'id': prog_name + " " + prog_version,
++ 'mail': "freedb-submit@freedb.org",
++ 'my_mail': "default"
++ },
++ 'freedb-au': {
++ 'host': "au.freedb.org",
++ 'id': prog_name + " " + prog_version,
++ 'mail': "freedb-submit@freedb.org",
++ 'my_mail': "default"
++ },
++ 'freedb-ca': {
++ 'host': "ca.freedb.org",
++ 'id': prog_name + " " + prog_version,
++ 'mail': "freedb-submit@freedb.org",
++ 'my_mail': "default"
++ },
++ 'freedb-es': {
++ 'host': "es.freedb.org",
++ 'id': prog_name + " " + prog_version,
++ 'mail': "freedb-submit@freedb.org",
++ 'my_mail': "default"
++ },
++ 'freedb-fi': {
++ 'host': "fi.freedb.org",
++ 'id': prog_name + " " + prog_version,
++ 'mail': "freedb-submit@freedb.org",
++ 'my_mail': "default"
++ },
++ 'freedb-jp': {
++ 'host': "jp.freedb.org",
++ 'id': prog_name + " " + prog_version,
++ 'mail': "freedb-submit@freedb.org",
++ 'my_mail': "default"
++ },
++ 'freedb-ru': {
++ 'host': "ru.freedb.org",
++ 'id': prog_name + " " + prog_version,
++ 'mail': "freedb-submit@freedb.org",
++ 'my_mail': "default"
++ },
++ 'freedb-uk': {
++ 'host': "uk.freedb.org",
++ 'id': prog_name + " " + prog_version,
++ 'mail': "freedb-submit@freedb.org",
++ 'my_mail': "default"
++ },
++ 'freedb-uk2': {
++ 'host': "uk2.freedb.org",
++ 'id': prog_name + " " + prog_version,
++ 'mail': "freedb-submit@freedb.org",
++ 'my_mail': "default"
++ },
++ 'freedb-us': {
++ 'host': "us.freedb.org",
++ 'id': prog_name + " " + prog_version,
++ 'mail': "freedb-submit@freedb.org",
++ 'my_mail': "default"
++ },
+ }
+
+ def interpret_db_file(all_tracks, todo, freedb_form_file, verb, dirs = 0, warn = None):
diff --git a/debian/patches/31_real_bitrate_progress.patch b/debian/patches/31_real_bitrate_progress.patch
new file mode 100644
index 0000000..928480a
--- /dev/null
+++ b/debian/patches/31_real_bitrate_progress.patch
@@ -0,0 +1,26 @@
+Put the real bitrate in the progress file. In case of VBR, jack used to
+put the bitrate of CBR into the jack.progress file. (Actually, why does
+track[RATE] not always contain the real rate?) Or maybe we should put the
+chosen quality rating in the progress file incase of OGG?
+
+diff -urN c/jack_main_loop.py jack-3.1.1+cvs20050801/jack_main_loop.py
+--- c/jack_main_loop.py 2006-02-07 00:57:23.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_main_loop.py 2006-02-07 01:17:15.000000000 +0000
+@@ -344,13 +344,14 @@
+ else:
+ global_done = global_done + exited_proc['track'][LEN]
+ if cf['_vbr']:
+- jack_status.enc_stat_upd(num, "[coding @" + '%s' % jack_functions.pprint_speed(speed) + "x done, %03.0fkbit]" % ((jack_utils.filesize(track[NAME] + ext) * 0.008) / (track[LEN] / 75.0)))
++ rate = int((jack_utils.filesize(track[NAME] + ext) * 0.008) / (track[LEN] / 75.0))
+ else:
+- jack_status.enc_stat_upd(num, "[coding @" + '%s' % jack_functions.pprint_speed(speed) + "x done, mp3 OK]")
++ rate = track[RATE]
++ jack_status.enc_stat_upd(num, "[coding @" + '%s' % jack_functions.pprint_speed(speed) + "x done, %dkbit" % rate)
++ jack_functions.progress(num, "enc", `rate`, jack_status.enc_status[num])
+ if not cf['_otf'] and not cf['_keep_wavs']:
+ os.remove(track[NAME] + ".wav")
+ space = space + jack_functions.tracksize(track)[WAV]
+- jack_functions.progress(num, "enc", `track[RATE]`, jack_status.enc_status[num])
+
+ else:
+ error("child process of unknown type (" + exited_proc['type'] + ") exited")
diff --git a/debian/patches/32_man_minus.patch b/debian/patches/32_man_minus.patch
new file mode 100644
index 0000000..2cd1dc3
--- /dev/null
+++ b/debian/patches/32_man_minus.patch
@@ -0,0 +1,84 @@
+Escape minus signs in the man page properly.
+
+'-' must be escaped ('\-') to be interpreted as minus. If you really
+intend a hyphen, write it as '\(hy' to emphasise that fact. See
+groff(7) and especially groff_char(7) for details, and also the thread
+starting with
+http://lists.debian.org/debian-devel/2003/debian-devel-200303/msg01481
+
+
+
+--- jack-3.1.1+cvs20050801~/jack.man 2006-04-02 21:01:32.000000000 +0200
++++ jack-3.1.1+cvs20050801/jack.man 2006-04-02 21:11:02.000000000 +0200
+@@ -148,9 +148,9 @@
+ .TP
+ .B \-\-edit-freedb
+ open an editor to change the CDDB information which has been obtained
+-previously (only useful with -Q).
++previously (only useful with \-Q).
+ .TP
+-.B \-\-encoder-name, -E string
++.B \-\-encoder-name, \-E string
+ use which encoder (default "oggenc")
+ .TP
+ .B \-e, \-\-encoders int
+@@ -260,7 +260,7 @@
+ .\" rip (non-functional, sorry)
+ .TP
+ .B \-\-quality int
+-vbr encoding quality. -1 is lowest, 10 highest (default 6). You can also specify a float.
++vbr encoding quality. \-1 is lowest, 10 highest (default 6). You can also specify a float.
+ .TP
+ .B \-q, \-\-query
+ do FreeDB query when all is done. This is useful if Jack was previously
+@@ -286,7 +286,7 @@
+ enough disk space.
+ .TP
+ .B \-\-remove-files
+-have Jack remove its temp jack*-files.
++have Jack remove its temp jack*\-files.
+ Be careful - don't delete them too early!
+ .TP
+ .B \-R, \-\-rename
+@@ -431,7 +431,7 @@
+ track_nn.mp3 plus jack.toc, jack.freedb, jack.progress. The last three are
+ used to store the state jack is in so it can resume work when interrupted.
+ .PP
+-Jack will create a directory called jack-xxxxxxxx for you, there it
++Jack will create a directory called jack\-xxxxxxxx for you, there it
+ stores all the file for the CD whose id is xxxxxxxx. After a FreeDB query
+ this directory is renamed to something human readable, like "Artist -
+ Title".
+@@ -444,7 +444,7 @@
+ .PP
+ Now let's try a FreeDB query:
+ .RS
+-jack -q
++jack \-q
+ .RE
+ If the query is successful the files will be renamed to something more readable
+ and will be tagged accordingly using ID3 or Vorbis tags. The file jack.freedb
+@@ -467,7 +467,7 @@
+ .B replacement_chars.
+ For example,
+ .RS
+-jack -Q --rename-fmt "%n-%t" --unusable-chars A I \; --replacement-chars a i \;
++jack \-Q \-\-rename-fmt "%n-%t" \-\-unusable-chars A I \; \-\-replacement-chars a i \;
+ .RE
+ will query the FreeDB server, rip and encode all tracks of the CD and save
+ the files in a format which will contain the track number and the title.
+@@ -492,12 +492,12 @@
+ .PP
+ All in one: query, rip, encode, cleanup:
+ .RS
+-jack -Q --remove-files
++jack \-Q \-\-remove-files
+ .RE
+ .PP
+ Editing / normalizing / stripping the WAV files before encoding:
+ .RS
+-jack -O --remove-files ; gnoise *wav ; jack -g *wav ; jack
++jack \-O \-\-remove-files ; gnoise *wav ; jack \-g *wav ; jack
+ .RE
+ Just replace gnoise by the operation you'd like to perform.
+ .SH ENVIRONMENT VARIABLES
diff --git a/debian/patches/33_flac_mutagen.patch b/debian/patches/33_flac_mutagen.patch
new file mode 100644
index 0000000..58897d1
--- /dev/null
+++ b/debian/patches/33_flac_mutagen.patch
@@ -0,0 +1,69 @@
+From: Joe Wreschnig <piman@sacredchao.net>
+
+Attached is a patch to jack_init.py and jack_tag.py to make them use
+Mutagen rather than pyflac. Mutagen exposes the stream info as
+f.info.{sample_rate,total_samples}, similar to pyflac. [pyflac is no longer
+maintained]
+
+
+diff -urN jack-3.1.1+cvs20050801~/jack_init.py jack-3.1.1+cvs20050801/jack_init.py
+--- jack-3.1.1+cvs20050801~/jack_init.py 2006-02-05 15:09:07.000000000 +0100
++++ jack-3.1.1+cvs20050801/jack_init.py 2006-04-04 22:49:42.000000000 +0200
+@@ -62,7 +62,7 @@
+ ogg = dummy_ogg()
+
+ try:
+- import flac.metadata
++ import mutagen.flac as flac
+ except ImportError:
+ flac = None
+
+diff -urN jack-3.1.1+cvs20050801~/jack_tag.py jack-3.1.1+cvs20050801/jack_tag.py
+--- jack-3.1.1+cvs20050801~/jack_tag.py 2006-04-04 22:59:44.000000000 +0200
++++ jack-3.1.1+cvs20050801/jack_tag.py 2006-04-04 22:59:10.000000000 +0200
+@@ -153,31 +153,21 @@
+ mp3file.close()
+ elif jack_helpers.helpers[cf['_encoder']]['target'] == "flac":
+ if flac:
+- chain = flac.metadata.Chain()
+- chain.read(mp3name)
+- it = flac.metadata.Iterator()
+- it.init(chain)
+- while 1:
+- if it.get_block_type() == flac.metadata.VORBIS_COMMENT:
+- block = it.get_block()
+- vc = flac.metadata.VorbisComment(block)
+- break
+- if not it.next():
+- break
+- if vc:
+- vc.comments['ALBUM'] = a_title.encode("utf-8")
+- vc.comments['TRACKNUMBER'] = `i[NUM]`
+- vc.comments['TITLE'] = t_name.encode("utf-8")
+- vc.comments['ARTIST'] = t_artist.encode("utf-8")
+- if cf['_id3_genre'] != -1:
+- vc.comments['GENRE'] = id3genres[cf['_id3_genre']]
+- if cf['_id3_year'] != -1:
+- vc.comments['DATE'] = `cf['_id3_year']`
+- chain.write(True, True)
++ f = flac.FLAC(mp3name)
++ if f.vc is None: f.add_vorbiscomment()
++ f.vc['ALBUM'] = a_title
++ f.vc['TRACKNUMBER'] = str(i[NUM])
++ f.vc['TITLE'] = t_name
++ f.vc['ARTIST'] = t_artist
++ if cf['_id3_genre'] != -1:
++ f.vc['GENRE'] = id3genres[cf['_id3_genre']]
++ if cf['_id3_year'] != -1:
++ f.vc['DATE'] = str(cf['_id3_year'])
++ f.save()
+ else:
+ print
+- print "Please install the pyflac module available at"
+- print "http://www.sacredchao.net/quodlibet/wiki/Download"
++ print "Please install the Mutagen module available at"
++ print "http://www.sacredchao.net/quodlibet/wiki/Development/Mutagen"
+ print "Without it, you'll not be able to tag FLAC tracks."
+ elif jack_helpers.helpers[cf['_encoder']]['target'] == "ogg":
+ vf = ogg.vorbis.VorbisFile(mp3name)
+
diff --git a/debian/patches/34_toc_invocation_fail.patch b/debian/patches/34_toc_invocation_fail.patch
new file mode 100644
index 0000000..3f208f6
--- /dev/null
+++ b/debian/patches/34_toc_invocation_fail.patch
@@ -0,0 +1,24 @@
+The error message when the toc program fails is misleading. Improve the
+message and remove some code that is not needed because it's tested
+elsewhere already. Debian #360465.
+
+--- a/jack_functions.py~ 2006-05-16 16:40:17.000000000 +0200
++++ b/jack_functions.py 2006-05-16 16:40:36.000000000 +0200
+@@ -119,16 +119,7 @@
+ l = p.readline()
+ exec(jack_helpers.helpers[toc_prog]['toc_fkt'])
+ if p.close():
+- if cf['_cd_device']:
+- try:
+- f = open(cf['_cd_device'], "r")
+- except IOError:
+- info("could not open " + cf['_cd_device'] + ". Check permissions and that a disc is inserted.")
+- else:
+- info("maybe " + toc_prog + " is not installed?")
+- else:
+- info("try setting cf['_cd_device'] to your CD device, e.g. /dev/cdrom")
+- error("could not read CD's TOC.")
++ error("%s failed - could not read CD's TOC." % toc_prog)
+ else:
+ return erg
+ else:
diff --git a/debian/patches/35_fix_xtermset.patch b/debian/patches/35_fix_xtermset.patch
new file mode 100644
index 0000000..896ddcc
--- /dev/null
+++ b/debian/patches/35_fix_xtermset.patch
@@ -0,0 +1,14 @@
+When xtermset_enable is set, jack resizes the window to something that is
+not high enough.
+
+--- jack_term.py~ 2006-05-16 18:09:55.000000000 +0200
++++ jack_term.py 2006-05-16 18:10:22.000000000 +0200
+@@ -106,7 +106,7 @@
+ want_y = want_y - 1
+ if jack_freedb.names_available:
+ want_y = want_y + 1
+- want_y = max(want_y, 7)
++ want_y += 7 # for the help panel
+ if (size_x, size_y) != (want_x, want_y):
+ try:
+ os.system("xtermset -geom %dx%d" % (want_x, want_y))
diff --git a/debian/patches/36_check_plugin.patch b/debian/patches/36_check_plugin.patch
new file mode 100644
index 0000000..5851092
--- /dev/null
+++ b/debian/patches/36_check_plugin.patch
@@ -0,0 +1,21 @@
+Bette error checking for the plugin import.
+
+--- jack_plugins.py~ 2006-05-20 14:16:41.000000000 +0200
++++ jack_plugins.py 2006-05-20 14:27:11.000000000 +0200
+@@ -26,8 +26,14 @@
+ def load_plugin(name, structure):
+ import_statement = "from jack_%s import %s" % (name, structure)
+ get_statement = "tmp = %s[name]" % structure
+- exec(import_statement) in locals()
+- exec(get_statement) in locals()
++ try:
++ exec(import_statement) in locals()
++ except ImportError, e:
++ error(str(e))
++ try:
++ exec(get_statement) in locals()
++ except KeyError:
++ error("Plugin %s doesn't have an appropriate helper definition." % name)
+ return tmp
+
+ def import_freedb_servers():
diff --git a/debian/patches/37_expand_CBR_acronym.patch b/debian/patches/37_expand_CBR_acronym.patch
new file mode 100644
index 0000000..753a75e
--- /dev/null
+++ b/debian/patches/37_expand_CBR_acronym.patch
@@ -0,0 +1,15 @@
+Change error message wording to say `fixed bitrate', which is
+more clear than `CBR'. Patch by Michael Banck. Debian #293336
+
+
+--- a/jack_checkopts.py.orig 2005-03-25 23:12:59.333566976 +0100
++++ b/jack_checkopts.py 2005-03-25 23:13:12.996489896 +0100
+@@ -188,7 +188,7 @@
+ cf.rupdate({'vbr': {'val': 0}}, "check")
+
+ if not cf['_vbr'] and not jack_helpers.helpers[cf['_encoder']].has_key('cmd'):
+- error("can't do CBR because " + cf['encoder']['val'] + " doesn't support it. Use -v")
++ error("can't do fixed bitrate because " + cf['encoder']['val'] + " doesn't support it. Use -v")
+
+ if cf['_ripper'] == "cdparanoia" and cf['_sloppy']:
+ jack_helpers.helpers['cdparanoia']['cmd'] = replace(jack_helpers.helpers['cdparanoia']['cmd'], "--abort-on-skip", "")
diff --git a/debian/patches/38_remove_gen_device.patch b/debian/patches/38_remove_gen_device.patch
new file mode 100644
index 0000000..f411858
--- /dev/null
+++ b/debian/patches/38_remove_gen_device.patch
@@ -0,0 +1,104 @@
+Remove (broken) generic device support from jack
+
+The current support in jack for "generic devices" is completely
+broken. While there is a --gen-device option (corresponding to %D in
+jack_helpers), it is actually not used anywhere - only in the cmd_old
+of cdda2wav but this is not used. The normal cmd uses %d which is the
+normal device.
+
+Furthermore, jack checks that the device specified as --gen-device
+exists (i.e. it assumes it's something like /dev/....). However,
+according to latest cdda2wav, it expects a SCSI string a la 1,0,0
+(bus, id, lun). Further tests show that using 1,0,0 or /dev/sr0
+on my system with a USB CD-ROM (i.e. one that shows up as SCSI) does
+not make any difference at all.
+
+My conclusion is that this "generic device" stuff is obsolete.
+Current Linux kernels should deal with devices properly, regardless of
+them being IDE or SCSI. In fact, I just saw a proposal to get rid of
+the ide-scsi stuff in the kernel.
+
+I'll therefore remove the (broken) generic device support from jack.
+
+
+diff -urN jack-3.1.1+cvs20050801~/jack_config.py jack-3.1.1+cvs20050801/jack_config.py
+--- jack-3.1.1+cvs20050801~/jack_config.py 2006-02-13 21:49:58.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_config.py 2006-02-13 21:50:33.000000000 +0000
+@@ -64,12 +64,6 @@
+ 'usage': "use which device for ripping",
+ 'long': 'device',
+ },
+- 'gen_device': {
+- 'type': types.StringType,
+- 'val': None,
+- 'doc': "cdda2wav may need the scsi generic device",
+- 'long': 'AUTO',
+- },
+ 'encoder': {
+ 'type': types.StringType,
+ 'val': "oggenc",
+diff -urN jack-3.1.1+cvs20050801~/jack_functions.py jack-3.1.1+cvs20050801/jack_functions.py
+--- jack-3.1.1+cvs20050801~/jack_functions.py 2006-02-13 21:49:58.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_functions.py 2006-02-13 21:50:24.000000000 +0000
+@@ -111,8 +111,6 @@
+ "Returns track list"
+ if jack_helpers.helpers[toc_prog].has_key('toc_cmd'):
+ cmd = string.replace(jack_helpers.helpers[toc_prog]['toc_cmd'], "%d", cf['_cd_device'])
+- if cf['_gen_device']:
+- cmd = string.replace(cmd, "%D", cf['_gen_device'])
+ p = os.popen(cmd)
+ start = 0
+ erg = []
+diff -urN jack-3.1.1+cvs20050801~/jack_helpers.py jack-3.1.1+cvs20050801/jack_helpers.py
+--- jack-3.1.1+cvs20050801~/jack_helpers.py 2006-02-13 21:49:58.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_helpers.py 2006-02-13 21:51:04.000000000 +0000
+@@ -350,7 +350,6 @@
+ ch = [ "none", "mono", "stereo", "three", "quad" ].index(ch)
+ erg.append([num, length, start, copy, pre, ch, 1, cf['_bitrate'], cf['_name'] % (num + 1)])
+ """,
+- 'toc_cmd_old': "cdda2wav --no-infofile -D %D -J -v 35 2>&1",
+ 'toc_fkt_old': r"""
+ new_c2w = 0
+ new_toc1 = 0
+diff -urN jack-3.1.1+cvs20050801~/jack_prepare.py jack-3.1.1+cvs20050801/jack_prepare.py
+--- jack-3.1.1+cvs20050801~/jack_prepare.py 2006-02-13 21:49:58.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_prepare.py 2006-02-13 21:50:18.000000000 +0000
+@@ -62,9 +62,6 @@
+ else:
+ jack_ripstuff.all_tracks = jack_functions.gettoc(cf['_toc_prog'])
+ toc_just_read = 1
+- # check that the generic device is usable, too
+- if cf['_gen_device'] and not os.access(cf['_gen_device'], os.R_OK | os.W_OK):
+- warning(r"""could not open generic device %s for reading and writing.""" % cf['_gen_device'])
+
+ if cf['_scan_dirs']:
+ dirs = [os.getcwd()]
+diff -urN jack-3.1.1+cvs20050801~/jack_workers.py jack-3.1.1+cvs20050801/jack_workers.py
+--- jack-3.1.1+cvs20050801~/jack_workers.py 2006-02-13 21:49:58.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_workers.py 2006-02-13 21:50:12.000000000 +0000
+@@ -78,7 +78,6 @@
+ if i == "%n": args.append(`track[NUM]`)
+ elif i == "%o": args.append(track[NAME].decode(cf['_charset'], "replace") + ".wav")
+ elif i == "%d": args.append(cf['_cd_device'])
+- elif i == "%D": args.append(cf['_gen_device'])
+ else: args.append(i)
+ data = start_new_process(args)
+ data['type'] = "ripper"
+@@ -165,7 +164,6 @@
+ for i in string.split(helpers[ripper]['otf-cmd']):
+ if i == "%n": args.append(`track[NUM]`)
+ elif i == "%d": args.append(cf['_cd_device'])
+- elif i == "%D": args.append(cf['_gen_device'])
+ else: args.append(i)
+ data['rip']['start_time'] = time.time()
+ pid = os.fork()
+@@ -205,8 +203,6 @@
+ args.append(track[NAME].decode(cf['_charset'], "replace") + jack_targets.targets[jack_helpers.helpers[cf['_encoder']]['target']]['file_extension'])
+ elif i == "%d":
+ args.append(cf['_cd_device'])
+- elif i == "%D":
+- args.append(cf['_gen_device'])
+ else:
+ args.append(i)
+ data['enc']['start_time'] = time.time()
+
diff --git a/debian/patches/39_main_loop_valueerror.patch b/debian/patches/39_main_loop_valueerror.patch
new file mode 100644
index 0000000..d340d2e
--- /dev/null
+++ b/debian/patches/39_main_loop_valueerror.patch
@@ -0,0 +1,49 @@
+Pressing ctrl-c randomly during ripping leads to ValueError. jack catches
+ValueError already in one place, but it needs to do the same in two other
+cases. Debian #352754.
+
+
+(-) SPACE:1.60GB waiting_WAVs:01 DAE:1+0 ENC:0+1 errors: 15 :-[ Traceback (most recent call last):
+ File "/usr/bin/jack", line 235, in ?
+ global_error = jack_main_loop.main_loop(mp3s_todo, wavs_todo, space, dae_queue, enc_queue, track1_offset)
+ File "/usr/lib/python2.3/site-packages/jack_main_loop.py", line 216, in main_loop
+ x = i['file'].read()
+ ValueError: I/O operation on closed file
+ *warning* abnormal exit
+ zsh: exit 1 jack
+1815:tbm@deprecation: ~/tmp/jack]
+
+
+diff -urN jack-3.1.1+cvs20050801~/jack_main_loop.py jack-3.1.1+cvs20050801/jack_main_loop.py
+--- jack-3.1.1+cvs20050801~/jack_main_loop.py 2006-02-14 01:13:10.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_main_loop.py 2006-02-14 01:13:42.000000000 +0000
+@@ -215,7 +215,7 @@
+ if os.uname()[0] == "Linux" and i['type'] != "image_reader":
+ try:
+ x = i['file'].read()
+- except IOError:
++ except (IOError, ValueError):
+ pass
+ else:
+ read_chars = 0
+@@ -223,7 +223,7 @@
+ while read_chars < jack_helpers.helpers[i['prog']]['status_blocksize']:
+ try:
+ xchar = i['file'].read(1)
+- except IOError:
++ except (IOError, ValueError):
+ break
+ x = x + xchar
+ read_chars = read_chars + 1
+@@ -263,9 +263,7 @@
+ x = ""
+ try:
+ x = exited_proc['file'].read()
+- except IOError:
+- pass
+- except ValueError:
++ except (IOError, ValueError):
+ pass
+ exited_proc['buf'] = (exited_proc['buf'] + x)[-jack_helpers.helpers[exited_proc['prog']]['status_blocksize']:]
+ exited_proc['file'].close()
+
diff --git a/debian/patches/40_enable_term.patch b/debian/patches/40_enable_term.patch
new file mode 100644
index 0000000..e8b1563
--- /dev/null
+++ b/debian/patches/40_enable_term.patch
@@ -0,0 +1,55 @@
+When a ripper is killed with ctrl-c, it is properly marked as "DAE failed
+with status 15, wav removed". However, afterwards pressing any key
+does precisely nothing, e.g. cursor keys or ctrl-l. ctrl-c does work,
+but messes up the display.
+
+The reason for that is that jack_term.disable() is called in the signal
+handler, but nobody calls jack_term.enable()... adding this works.
+
+In addition, let's ignore ctrl-c in the signal handler function because
+otherwise people could press ctrl-c again within the signal handler (e.g.
+while jack is waiting for the user to press enter when --wait is on), and
+then we get the display problem again because jack_term.enable() is not
+called.
+
+Debian #352755
+
+P.S. I'm not quite sure whether this fix (and 56_ctrl_c_termset.patch,
+which is related) are correct. Basically, according to the code, pressing
+Ctrl-C should clean up and then exit the program. However, for some reason
+jack never exits; all that happens is that the helpers are killed off. The
+sig variable seems to indicate whether we're really exiting or not...
+unfortunately, I have no idea why jack doesn't exit all the time or what
+the correct behaviour should be. See http://bugs.debian.org/196429 for
+some discussion about this.
+
+
+Depends on 21_fallback_ripper.patch
+
+
+diff -urN jack-3.1.1+cvs20050801~/jack_display.py jack-3.1.1+cvs20050801/jack_display.py
+--- jack-3.1.1+cvs20050801~/jack_display.py 2006-02-21 00:38:12.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_display.py 2006-02-21 00:38:34.000000000 +0000
+@@ -74,6 +74,10 @@
+ else:
+ exit_code = 0
+
++ # Ignore Ctrl-C while we disable and enable curses, otherwise there may
++ # be display problems.
++ sigint_handler = signal.getsignal(signal.SIGINT)
++ signal.signal(signal.SIGINT, signal.SIG_IGN)
+ jack_term.disable()
+
+ if sig:
+@@ -93,6 +97,10 @@
+ if cf['_wait_on_quit']:
+ raw_input("press ENTER to exit")
+
++ if sig:
++ jack_term.enable()
++ signal.signal(signal.SIGINT, sigint_handler)
++
+ sys.exit(exit_code)
+
+ #/ end of sig_handler /#
+
diff --git a/debian/patches/41_nicify_wait.patch b/debian/patches/41_nicify_wait.patch
new file mode 100644
index 0000000..ad121cc
--- /dev/null
+++ b/debian/patches/41_nicify_wait.patch
@@ -0,0 +1,24 @@
+When --wait is on jack always display "press ENTER to exit" when leaving
+the signal handler. This message is not optimal since it's also displayed
+when you e.g. kill a ripper or encoder. Check whether sig is set and adapt
+the message accordingly.
+
+Depends on 40_enable_term.patch
+
+
+diff -urN jack-3.1.1+cvs20050801~/jack_display.py jack-3.1.1+cvs20050801/jack_display.py
+--- jack-3.1.1+cvs20050801~/jack_display.py 2006-02-21 00:39:23.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_display.py 2006-02-21 00:39:50.000000000 +0000
+@@ -95,7 +95,10 @@
+ progress("all", "err", "abnormal exit (code %i), check %s and %s" % (exit_code, cf['_err_file'], cf['_out_file']))
+
+ if cf['_wait_on_quit']:
+- raw_input("press ENTER to exit")
++ if sig:
++ raw_input("press ENTER\n")
++ else:
++ raw_input("press ENTER to exit\n")
+
+ if sig:
+ jack_term.enable()
+
diff --git a/debian/patches/42_cd_device_fallback.patch b/debian/patches/42_cd_device_fallback.patch
new file mode 100644
index 0000000..5c40ad7
--- /dev/null
+++ b/debian/patches/42_cd_device_fallback.patch
@@ -0,0 +1,56 @@
+If the user doesn't specify a device and the default (/dev/cdrom) doesn't
+exist, it would be nice if jack could fall back to the device(s) listed in
+/proc/sys/dev/cdrom/info (at least on Linux). According to the
+linux-kernel mailing list, this is a stable interface.
+
+Debian #353551
+Depends on 21_fallback_ripper.patch
+
+diff -urN jack-3.1.1+cvs20050801~/jack_checkopts.py jack-3.1.1+cvs20050801/jack_checkopts.py
+--- jack-3.1.1+cvs20050801~/jack_checkopts.py 2006-07-02 20:09:50.000000000 +0200
++++ jack-3.1.1+cvs20050801/jack_checkopts.py 2006-07-02 20:10:24.000000000 +0200
+@@ -254,3 +254,44 @@
+ if not jack_utils.in_path(helper):
+ error("Helper %s '%s' not found on your system." % (t, helper))
+
++ # If the default CD device doesn't exist, see whether we can find another one
++ if ('cd_device' not in all_keys and cf["rip_from_device"]["val"] and
++ not os.path.exists(cf["cd_device"]["val"])):
++ default = cf["cd_device"]["val"]
++ devices = []
++ # All CD devices can be found in /proc on Linux
++ cdrom_info = "/proc/sys/dev/cdrom/info"
++ if os.path.exists(cdrom_info):
++ try:
++ info = open(cdrom_info, "r")
++ except (IOError, OSError):
++ pass
++ else:
++ for line in info.readlines():
++ if line.startswith("drive name:"):
++ devices = ["/dev/" + x for x in line.rstrip().split("\t")[2:]]
++ break
++ info.close()
++ message = "Default CD device %s does not exist" % default
++ if not devices:
++ warning("%s." % message)
++ elif len(devices) == 1:
++ warning("%s, using %s." % (message, devices[0]))
++ cf.rupdate({'cd_device': {'val': devices[0]}}, "check")
++ else:
++ warning("%s but there are several CD devices." % message)
++ for i in range(len(devices)):
++ print "%2d" % (i+1) + ".) " + devices[i]
++ input = 0
++ while input <= 0 or input > len(devices):
++ try:
++ input = raw_input("Please choose: ")
++ except KeyboardInterrupt:
++ sys.exit(0)
++ if input.isdigit():
++ input = int(input)
++ else:
++ input = 0
++ devices[0] = devices[input-1]
++ cf.rupdate({'cd_device': {'val': devices[0]}}, "check")
++
diff --git a/debian/patches/43_string_option.patch b/debian/patches/43_string_option.patch
new file mode 100644
index 0000000..a6229b1
--- /dev/null
+++ b/debian/patches/43_string_option.patch
@@ -0,0 +1,22 @@
+option is already a string, so don't convert it to a string again,
+otherwise we get multiple quotation marks.
+
+122:tbm@deception: ~/tmp/jack/in_bloom_cd1] jack -g
+This is jack 3.1.1 (C)2004 Arne Zellentin <zarne@users.sf.net>
+ *error* option `'guess_mp3s'' takes a non-empty list (which may be terminated
+ by ";")
+zsh: exit 1 jack -g
+
+
+diff -urN orig/jack_argv.py jack-3.1.1+cvs20050801/jack_argv.py
+--- orig/jack_argv.py 2006-02-27 12:38:42.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_argv.py 2006-02-27 12:39:04.000000000 +0000
+@@ -148,7 +148,7 @@
+ if l and type(l) == types.ListType:
+ return i, l
+ else:
+- return None, "option `%s' takes a non-empty list (which may be terminated by \";\")" % `option`
++ return None, "option `%s' takes a non-empty list (which may be terminated by \";\")" % option
+ # default
+ return None, "unknown argument type for option `%s'." % option
+
diff --git a/debian/patches/44_guess_toc_ogg_flac.patch b/debian/patches/44_guess_toc_ogg_flac.patch
new file mode 100644
index 0000000..5ce4fc5
--- /dev/null
+++ b/debian/patches/44_guess_toc_ogg_flac.patch
@@ -0,0 +1,89 @@
+Implement OGG and FLAC support for --guess-toc. SourceForge #1089407
+
+Also fix a problem with the progress information ("ren") when a filename
+contains Unicode chars.
+
+Depends on 33_flac_mutagen.patch
+
+
+diff -urN jack-3.1.1+cvs20050801~/jack_functions.py jack-3.1.1+cvs20050801/jack_functions.py
+--- jack-3.1.1+cvs20050801~/jack_functions.py 2006-04-04 23:09:17.000000000 +0200
++++ jack-3.1.1+cvs20050801/jack_functions.py 2006-04-04 23:25:59.000000000 +0200
+@@ -33,6 +33,8 @@
+ import jack_helpers
+
+ from jack_globals import *
++from jack_init import ogg
++from jack_init import flac
+
+ progress_changed = None
+
+@@ -152,21 +154,17 @@
+ erg = []
+ progr = []
+ for i in names:
+- i_name = os.path.basename(i)[:-4]
+- i_ext = string.upper(os.path.basename(i)[-4:])
++ i_name, i_ext = os.path.splitext(os.path.basename(i))
++ i_ext = i_ext.upper()
++ # erg: NUM, LEN, START, COPY, PRE, CH, RIP, RATE, NAME
+ if i_ext == ".MP3":
+ x = jack_mp3.mp3format(i)
+ if not x:
+ error("could not get MP3 info for file \"%x\"" % i)
+ blocks = int(x['length'] * CDDA_BLOCKS_PER_SECOND + 0.5)
+- # NUM, LEN, START, COPY, PRE, CH, RIP, RATE,
+- # NAME
+- erg.append([num, blocks, start, 0, 0, 2, 1, x['bitrate'],
+- i_name])
++ erg.append([num, blocks, start, 0, 0, 2, 1, x['bitrate'], i_name])
+ progr.append([num, "dae", " * [ simulated ]"])
+ progr.append([num, "enc", `x['bitrate']`, "[ s i m u l a t e d %3ikbit]" % (x['bitrate'] + 0.5)])
+- if cf['_name'] % num != i_name:
+- progr.append([num, "ren", cf['_name'] % num + "-->" + i_name])
+ elif i_ext == ".WAV":
+ x = sndhdr.whathdr(i)
+ if not x:
+@@ -190,14 +188,37 @@
+ blocks = blocks / CDDA_BLOCKSIZE
+ erg.append([num, blocks, start, 0, 0, 2, 1, cf['_bitrate'], i_name])
+ progr.append([num, "dae", " =p [ s i m u l a t e d ]"])
+- if cf['_name'] % num != i_name:
+- progr.append([num, "ren", cf['_name'] % num + "-->" + i_name])
+ elif i_ext == ".OGG":
+- error("you still have to wait for ogg support for this operation, sorry.")
++ if ogg:
++ x = ogg.vorbis.VorbisFile(i)
++ blocks = int(x.time_total(0) * CDDA_BLOCKS_PER_SECOND + 0.5)
++ bitrate = temp_rate = int(x.raw_total(0) * 8 / x.time_total(0) / 1000 + 0.5)
++ erg.append([num, blocks, start, 0, 0, 2, 1, bitrate, i_name])
++ progr.append([num, "dae", " * [ simulated ]"])
++ progr.append([num, "enc", `bitrate`, "[ s i m u l a t e d %3ikbit]" % bitrate])
++ else:
++ error("The OGG Python bindings are not installed.")
+ elif i_ext == ".FLAC":
+- error("you still have to wait for FLAC support for this ooperation, sorry.")
++ if flac:
++ # TODO: move all of this duplicate code (see update_progress in
++ # jack_prepare.py) into a jack_flac or jack_audio or jack_formats.
++ # The same goes for the OGG stuff above
++ f = flac.FLAC(i)
++ size = os.path.getsize(i)
++ if f.info and size:
++ blocks = int(float(f.info.total_samples)/f.info.sample_rate * CDDA_BLOCKS_PER_SECOND + 0.5)
++ bitrate = int(size * 8 * f.info.sample_rate / f.info.total_samples / 1000)
++ else:
++ blocks = bitrate = 0
++ erg.append([num, blocks, start, 0, 0, 2, 1, bitrate, i_name])
++ progr.append([num, "dae", " * [ simulated ]"])
++ progr.append([num, "enc", `bitrate`, "[ s i m u l a t e d %3ikbit]" % bitrate])
++ else:
++ error("The FLAC Python bindings are not installed.")
+ else:
+ error("this is neither .mp3 nor .ogg nor .wav nor .flac: %s" % i)
++ if cf['_name'] % num != i_name:
++ progr.append([num, "ren", cf['_name'] % num + "-->" + unicode(i_name, cf['_charset'], "replace")])
+ num = num + 1
+ start = start + blocks
+ for i in progr: # this is deferred so that it is only written if no
+
diff --git a/debian/patches/45_fix_normalize_example.patch b/debian/patches/45_fix_normalize_example.patch
new file mode 100644
index 0000000..acd426d
--- /dev/null
+++ b/debian/patches/45_fix_normalize_example.patch
@@ -0,0 +1,16 @@
+The example about normalizing WAVs is broken since jack will put WAV files
+in a sub-directory. Add the -D option so this is not done. SourceForge
+#1311567
+
+diff -urN orig/jack.man jack-3.1.1+cvs20050801/jack.man
+--- orig/jack.man 2006-02-27 13:33:48.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack.man 2006-02-27 13:34:22.000000000 +0000
+@@ -496,7 +496,7 @@
+ .PP
+ Editing / normalizing / stripping the WAV files before encoding:
+ .RS
+-jack \-O \-\-remove-files ; gnoise *wav ; jack \-g *wav ; jack
++jack \-O \-D \-\-remove-files ; gnoise *wav ; jack \-g *wav ; jack
+ .RE
+ Just replace gnoise by the operation you'd like to perform.
+ .SH PLUG-INS
diff --git a/debian/patches/46_case_insens_fn.dpatch b/debian/patches/46_case_insens_fn.dpatch
new file mode 100644
index 0000000..93948d7
--- /dev/null
+++ b/debian/patches/46_case_insens_fn.dpatch
@@ -0,0 +1,33 @@
+Make the search for files in jack_prepare case insensitive (like
+jack_function) does, and use the same error message in jack_function and
+jack_prepare.
+
+diff -urN orig/jack_functions.py jack-3.1.1+cvs20050801/jack_functions.py
+--- orig/jack_functions.py 2006-02-27 13:50:37.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_functions.py 2006-02-27 13:52:10.000000000 +0000
+@@ -232,7 +232,7 @@
+ else:
+ error("The FLAC Python bindings are not installed.")
+ else:
+- error("this is neither .mp3 nor .ogg nor .wav nor .flac: %s" % i)
++ error("don't know how to handle %s files." % i_ext)
+ if cf['_name'] % num != i_name:
+ progr.append([num, "ren", cf['_name'] % num + "-->" + unicode(i_name, cf['_charset'], "replace")])
+ num = num + 1
+diff -urN jack-3.1.1+cvs20050801~/jack_prepare.py jack-3.1.1+cvs20050801/jack_prepare.py
+--- jack-3.1.1+cvs20050801~/jack_prepare.py 2006-04-04 23:36:28.000000000 +0200
++++ jack-3.1.1+cvs20050801/jack_prepare.py 2006-04-04 23:37:10.000000000 +0200
+@@ -339,10 +339,10 @@
+ jack_functions.progress(num, "dae", status[num]['dae'])
+ if not status[num]['enc']:
+ if os.path.exists(i[NAME] + ext):
+- if ext == ".mp3":
++ if ext.upper() == ".MP3":
+ x = jack_mp3.mp3format(i[NAME] + ext)
+ temp_rate = x['bitrate']
+- elif ext == ".ogg":
++ elif ext.upper() == ".OGG" and ogg:
+ x = ogg.vorbis.VorbisFile(i[NAME] + ext)
+ temp_rate = int(x.raw_total(0) * 8 / x.time_total(0) / 1000 + 0.5)
+ else:
+
diff --git a/debian/patches/47_locale_check.patch b/debian/patches/47_locale_check.patch
new file mode 100644
index 0000000..90711fd
--- /dev/null
+++ b/debian/patches/47_locale_check.patch
@@ -0,0 +1,26 @@
+jack produces a traceback when the locale is not known or hasn't been
+generated. Therefore check whether it is known.
+
+--- a/jack_config.py~ 2006-04-04 19:43:03.000000000 +0200
++++ b/jack_config.py 2006-04-04 19:45:11.000000000 +0200
+@@ -22,12 +22,20 @@
+ import string
+ import jack_misc
+ import locale
++import sys
+
+ import jack_version
+ from jack_globals import *
+
+ # this must be filled manually (done in main)
+
++# we need a working locale
++try:
++ locale.getpreferredencoding()
++except locale.Error, e:
++ print "Locale problem:", e
++ sys.exit(1)
++
+ # config space with attributes
+
+ cf = jack_misc.dict2({
diff --git a/debian/patches/48_search_base_dir.patch b/debian/patches/48_search_base_dir.patch
new file mode 100644
index 0000000..19e5212
--- /dev/null
+++ b/debian/patches/48_search_base_dir.patch
@@ -0,0 +1,21 @@
+running "jack -Q" twice from e.g. $HOME will result in an error in the
+second case that the directory already exists. This is because jack
+doesn't find the existing directory, makes a new generic jack-* dir and
+then tries to rename it - but that fails since there's an existing dir
+already. jack needs to search base_dir for an existing dir.
+
+--- jack_prepare.py~ 2006-04-04 22:45:10.000000000 +0200
++++ jack_prepare.py 2006-04-04 22:45:58.000000000 +0200
+@@ -72,6 +72,12 @@
+
+ if cf['_scan_dirs']:
+ dirs = [os.getcwd()]
++ # Also scan base_dir since it's not guaranteed that users
++ # run jack in base_dir
++ if cf['_base_dir']:
++ cf['_base_dir'] = expand(cf['_base_dir'])
++ if os.path.exists(cf['_base_dir']) and cf['_base_dir'] not in dirs:
++ dirs.append(cf['_base_dir'])
+ else:
+ dirs = cf['_searchdirs']
+
diff --git a/debian/patches/49_nicer_ripper_encoder.patch b/debian/patches/49_nicer_ripper_encoder.patch
new file mode 100644
index 0000000..c463dd8
--- /dev/null
+++ b/debian/patches/49_nicer_ripper_encoder.patch
@@ -0,0 +1,32 @@
+When you specify an unknown ripper or encoder, jack prints a python
+array...
+
+247:tbm@reyes: ~/tmp/jack] jack -E dasdas
+This is jack 3.1.1 (C)2004 Arne Zellentin <zarne@users.sf.net>
+ *error* Invalid encoder, choose one of ['bladeenc', 'xing', 'mppenc', 'lame',
+ 'oggenc', 'l3enc', 'gogo', 'mp3enc', 'flac', 'lame-user']
+zsh: exit 1 jack -E dasdas
+
+Print a more readable message instead.
+
+
+diff -urN jack-3.1.1+cvs20050801~/jack_checkopts.py jack-3.1.1+cvs20050801/jack_checkopts.py
+--- jack-3.1.1+cvs20050801~/jack_checkopts.py 2006-04-04 23:40:24.000000000 +0200
++++ jack-3.1.1+cvs20050801/jack_checkopts.py 2006-04-04 23:41:39.000000000 +0200
+@@ -173,14 +173,14 @@
+ for i in jack_helpers.helpers.keys():
+ if jack_helpers.helpers[i]['type'] == "encoder":
+ dummy.append(i)
+- error("Invalid encoder, choose one of " + `dummy`)
++ error("Invalid encoder, choose one of " + ", ".join(dummy))
+
+ if not jack_helpers.helpers.has_key(cf['_ripper']) or jack_helpers.helpers[cf['_ripper']]['type'] != "ripper":
+ dummy = []
+ for i in jack_helpers.helpers.keys():
+ if jack_helpers.helpers[i]['type'] == "ripper":
+ dummy.append(i)
+- error("Invalid ripper, choose one of " + `dummy`)
++ error("Invalid ripper, choose one of " + ", ".join(dummy))
+
+ if (cf['vbr_quality']['val'] > 10) or (cf['vbr_quality']['val'] < -1):
+ error("invalid vbr quality, must be between -1 and 10")
diff --git a/debian/patches/50_check_ripper_encoder.patch b/debian/patches/50_check_ripper_encoder.patch
new file mode 100644
index 0000000..5e8b95b
--- /dev/null
+++ b/debian/patches/50_check_ripper_encoder.patch
@@ -0,0 +1,34 @@
+Check whether a command passed via --ripper/--encoder actually exists.
+
+
+Depends on 21_fallback_ripper.patch
+
+
+diff -urN jack-3.1.1+cvs20050801~/jack_checkopts.py jack-3.1.1+cvs20050801/jack_checkopts.py
+--- jack-3.1.1+cvs20050801~/jack_checkopts.py 2006-05-20 14:02:09.000000000 +0200
++++ jack-3.1.1+cvs20050801/jack_checkopts.py 2006-05-20 14:08:54.000000000 +0200
+@@ -228,6 +228,7 @@
+ def check_rc(cf, global_cf, user_cf, argv_cf):
+
+ all_keys = global_cf.keys() + user_cf.keys() + argv_cf.keys()
++ userdef_keys = user_cf.keys() + argv_cf.keys()
+ if 'base_dir' not in all_keys:
+ warning("You have no standard location set, putting files into the current directory. Please consider setting base_dir in ~/.jack3rc.")
+
+@@ -244,6 +245,15 @@
+ else:
+ error("No valid ripper found on your system.")
+
++ # Check whether ripper and encoder exist in $PATH. Skip the check if
++ # it's a plugin since we cannot assume the name of the plugin
++ # corresponds to the executable.
++ for t in ("ripper", "encoder"):
++ helper = cf[t]["val"]
++ if t in userdef_keys and not helper.startswith("plugin_"):
++ if not jack_utils.in_path(helper):
++ error("Helper %s '%s' not found on your system." % (t, helper))
++
+ # If the default CD device doesn't exist, see whether we can find another one
+ if ('cd_device' not in all_keys and cf["rip_from_device"]["val"] and
+ not os.path.exists(cf["cd_device"]["val"])):
+
diff --git a/debian/patches/51_error_not_block_device.patch b/debian/patches/51_error_not_block_device.patch
new file mode 100644
index 0000000..8b6282e
--- /dev/null
+++ b/debian/patches/51_error_not_block_device.patch
@@ -0,0 +1,36 @@
+Fix an error when the --device passed is a directory. Debian #360337
+
+$ jack --device=/dev
+This is jack 3.1.1 (C)2004 Arne Zellentin <zarne@users.sf.net>
+Traceback (most recent call last):
+File "/usr/lib/python2.3/site-packages/jack_functions.py", line 148, in gettoc
+ exec(jack_helpers.helpers[toc_prog]['toc_fkt'])
+ File "<string>", line 11, in ?
+IndexError: tuple index out of range
+ *error* CDDB.py could not read the disk's TOC. If you already ripped the CD,
+ you'll have to cd into the directory which is either named after the
+ CD's title or still called jack-xxxxxxxx (xxxxxxxx is a hex number).
+
+
+--- a/jack_functions.py~ 2006-04-05 16:04:06.000000000 +0200
++++ b/jack_functions.py 2006-04-05 16:39:56.000000000 +0200
+@@ -21,6 +21,7 @@
+ import traceback
+ import sndhdr
+ import types
++import stat
+ import string
+ import sys
+ import os
+--- a/jack_helpers.py~ 2006-04-05 16:37:52.000000000 +0200
++++ b/jack_helpers.py 2006-04-05 16:39:25.000000000 +0200
+@@ -509,6 +509,8 @@
+ error("Device %s does not exist!" % cf['_cd_device'])
+ if not os.access(cf['_cd_device'], os.R_OK):
+ error("You don't have permission to access device %s!" % cf['_cd_device'])
++if not stat.S_ISBLK(os.stat(cf['_cd_device'])[stat.ST_MODE]):
++ error("Device %s is not a block device!" % cf['_cd_device'])
+ try:
+ device = cdrom.open(cf['_cd_device'])
+ (first, last) = cdrom.toc_header(device)
+
diff --git a/debian/patches/52_cdparanoia_toc.patch b/debian/patches/52_cdparanoia_toc.patch
new file mode 100644
index 0000000..d3decb4
--- /dev/null
+++ b/debian/patches/52_cdparanoia_toc.patch
@@ -0,0 +1,69 @@
+Make the cdparanoia TOC parsing more robust (and clean up the code while
+we're at it). Debian #361164.
+
+
+This is jack 3.1.1 (C)2004 Arne Zellentin <zarne@users.sf.net>
+Traceback (most recent call last):
+ File "/usr/bin/jack", line 134, in ?
+ jack_prepare.filter_tracks(toc_just_read, status)
+ File "/usr/lib/python2.3/site-packages/jack_prepare.py", line 216, in
+filter_tracks
+ ripper_tracks = jack_functions.gettoc(cf['_ripper'])
+ File "/usr/lib/python2.3/site-packages/jack_functions.py", line 125, in
+gettoc exec(jack_helpers.helpers[toc_prog]['toc_fkt'])
+ File "<string>", line 10, in ?
+ValueError: invalid literal for int(): 401: Invalid track number
+
+
+
+diff -urN jack-3.1.1+cvs20050801~/jack_helpers.py jack-3.1.1+cvs20050801/jack_helpers.py
+--- jack-3.1.1+cvs20050801~/jack_helpers.py 2006-04-07 03:58:48.000000000 +0200
++++ jack-3.1.1+cvs20050801/jack_helpers.py 2006-04-07 04:25:28.000000000 +0200
+@@ -297,19 +297,38 @@
+ """,
+ #'toc': 1, # we can't generate correct freedb IDs with cdparanoia.
+ 'toc_cmd': "cdparanoia -d %d -Q 2>&1",
++# The output from cdparanoia which we parse looks like this:
++
++# cdparanoia III release 9.8 (March 23, 2001)
++# (C) 2001 Monty <monty@xiph.org> and Xiphophorus
++# ...
++# track length begin copy pre ch
++# ===========================================================
++# 1. 13584 [03:01.09] 0 [00:00.00] no no 2
++# 2. 13769 [03:03.44] 13584 [03:01.09] no no 2
++# ...
++# TOTAL 121128 [26:55.03] (audio only)
++
++# That is, we look for a line only consisting of === signs as the start,
++# for a line starting with "TOTAL" as the end, and take everything
++# inbetween (to be precise: the first number on each line)
+ 'toc_fkt': r"""
+-while l:
++for l in p.readlines():
+ l = string.rstrip(l)
+- if l and l[0:5] == "TOTAL":
++ if not l:
++ continue
++ if l.startswith("TOTAL"):
+ start = 0
+- if l and l == '=' * (len(l)):
++ elif l == ('=' * len(l)):
+ start = 1
+- elif l and start:
+- l = string.split(l, '.', 1)
+- num = int(l[0])
+- l = string.split(l[1])
+- erg.append([num, int(l[0]), int(l[2]), l[4] == 'OK', l[5] == 'yes', int(l[6]), 1, cf['_bitrate'], cf['_name'] % num])
+- l = p.readline()
++ elif start:
++ l = l.split('.', 1)
++ if l[0].lstrip().isdigit():
++ num = int(l[0])
++ l = l[1].split()
++ erg.append([num, int(l[0]), int(l[2]), l[4] == 'OK', l[5] == 'yes', int(l[6]), 1, cf['_bitrate'], cf['_name'] % num])
++ else:
++ warning("Cannot parse cdrecord TOC line: " + ". ".join(l))
+ """,
+ },
+
diff --git a/debian/patches/53_no_tag_when_freedb_fails.patch b/debian/patches/53_no_tag_when_freedb_fails.patch
new file mode 100644
index 0000000..00469ef
--- /dev/null
+++ b/debian/patches/53_no_tag_when_freedb_fails.patch
@@ -0,0 +1,38 @@
+Don't try to tag files when no FreeDB data is available - this can
+happen when cont_failed_query is set. Debian #361290
+
+
+dlakelan@mooch64:~$ jack
+This is jack 3.1.1 (C)2004 Arne Zellentin <zarne@users.sf.net>
+ *info* querying...
+ *warning* 202 No match for disc ID 520ded06. How about trying another
+ --server?
+
+freedb search failed, continue? (y/N) y
+Options: vbr read-ahead=99 id=520ded06 len=59:25 | press Q to quit
+The final status was:
+track_01: 12.4x [ DAE done with cdda2wav ] [coding @16.3x done, 135kbit
+track_02: 17.7x [ DAE done with cdda2wav ] [coding @14.8x done, 129kbit
+track_03: 19.7x [ DAE done with cdda2wav ] [coding @13.0x done, 130kbit
+track_04: 23.5x [ DAE done with cdda2wav ] [coding @16.8x done, 136kbit
+track_05: 24.0x [ DAE done with cdda2wav ] [coding @17.0x done, 132kbit
+track_06: 23.5x [ DAE done with cdda2wav ] [coding @16.7x done, 134kbit
+Tagging.Traceback (most recent call last):
+ File "/usr/bin/jack", line 274, in ?
+ jack_tag.tag(freedb_rename)
+ File "/usr/lib/python2.3/site-packages/jack_tag.py", line 182, in tag
+ oggi.add_tag('ALBUM', a_title.encode("utf-8"))
+AttributeError: 'NoneType' object has no attribute 'encode'
+
+
+diff -urN jack-3.1.1+cvs20050801~/jack_prepare.py jack-3.1.1+cvs20050801/jack_prepare.py
+--- jack-3.1.1+cvs20050801~/jack_prepare.py 2006-04-07 20:02:26.000000000 +0200
++++ jack-3.1.1+cvs20050801/jack_prepare.py 2006-04-07 20:02:44.000000000 +0200
+@@ -486,6 +486,7 @@
+ if string.upper(x[0]) != "Y":
+ sys.exit(0)
+ cf['_query_on_start'] = 0
++ cf['_set_id3tag'] = 0
+ else:
+ jack_display.exit()
+
diff --git a/debian/patches/54_check_cont_failed_query.patch b/debian/patches/54_check_cont_failed_query.patch
new file mode 100644
index 0000000..f2432d9
--- /dev/null
+++ b/debian/patches/54_check_cont_failed_query.patch
@@ -0,0 +1,19 @@
+I don't see any good reason why cont_failed_query would turn on
+query_on_start and set_id3tag. After all, all this option is supposed to
+do is to cause jack not to fail when FreeDB is unssuccfully queried -
+however, it should be up to users to initiate the query.
+
+
+diff -urN jack-3.1.1+cvs20050801~/jack_checkopts.py jack-3.1.1+cvs20050801/jack_checkopts.py
+--- jack-3.1.1+cvs20050801~/jack_checkopts.py 2006-04-07 20:02:26.000000000 +0200
++++ jack-3.1.1+cvs20050801/jack_checkopts.py 2006-04-07 20:03:32.000000000 +0200
+@@ -50,9 +50,6 @@
+ if cf2.has_key('query_on_start') and cf2['query_on_start']['val']:
+ cf.rupdate({'set_id3tag': {'val': 1}}, "check")
+
+- if cf2.has_key('cont_failed_query') and cf2['cont_failed_query']['val']:
+- cf.rupdate({'query_on_start': {'val': 1}, 'set_id3tag':{'val': 1}}, "check")
+-
+ if cf2.has_key('create_dirs') and cf2['create_dirs']['val']:
+ cf.rupdate({'rename_dir': {'val': 1}}, "check")
+
diff --git a/debian/patches/55_fix_sloppy.patch b/debian/patches/55_fix_sloppy.patch
new file mode 100644
index 0000000..c1bafe0
--- /dev/null
+++ b/debian/patches/55_fix_sloppy.patch
@@ -0,0 +1,25 @@
+Fix "replace" call in undocumented command line option. Debian #362676
+
+1126:tbm@reyes: ~/tmp/jack] jack "--I-swear-I'll-never-give-these-files-to-anyone,-including-hot-babes-TM"
+This is jack 3.1.1 (C)2004 Arne Zellentin <zarne@users.sf.net>
+Traceback (most recent call last):
+ File "/usr/bin/jack", line 88, in ?
+ jack_checkopts.consistency_check(cf)
+ File "/usr/lib/python2.3/site-packages/jack_checkopts.py", line 211, in consistency_check
+ jack_helpers.helpers['cdparanoia']['cmd'] = replace(jack_helpers.helpers['cdparanoia']['cmd'], "--abort-on-skip", "")
+NameError: global name 'replace' is not defined
+
+
+--- a/jack_checkopts.py~ 2006-04-15 19:20:23.000000000 +0200
++++ b/jack_checkopts.py 2006-04-15 19:21:06.000000000 +0200
+@@ -208,8 +208,8 @@
+ error("can't do fixed bitrate because " + cf['encoder']['val'] + " doesn't support it. Use -v")
+
+ if cf['_ripper'] == "cdparanoia" and cf['_sloppy']:
+- jack_helpers.helpers['cdparanoia']['cmd'] = replace(jack_helpers.helpers['cdparanoia']['cmd'], "--abort-on-skip", "")
+- jack_helpers.helpers['cdparanoia']['otf-cmd'] = replace(jack_helpers.helpers['cdparanoia']['otf-cmd'], "--abort-on-skip", "")
++ jack_helpers.helpers['cdparanoia']['cmd'] = jack_helpers.helpers['cdparanoia']['cmd'].replace("--abort-on-skip", "")
++ jack_helpers.helpers['cdparanoia']['otf-cmd'] = jack_helpers.helpers['cdparanoia']['otf-cmd'].replace("--abort-on-skip", "")
+
+ if cf['_query_on_start'] and cf['_query_when_ready']:
+ error("it doesn't make sense to query now _and_ when finished.")
diff --git a/debian/patches/56_ctrl_c_termset.patch b/debian/patches/56_ctrl_c_termset.patch
new file mode 100644
index 0000000..fd477fd
--- /dev/null
+++ b/debian/patches/56_ctrl_c_termset.patch
@@ -0,0 +1,71 @@
+When xtermset_enable is set, pressing ctrl-c influences the window size:
+pressing ctrl-c one time (or any odd number) leads to the original window
+size whereas even number lead to the new window size. This is because
+jack_term.enable() and .disable() are called and those call xtermset_enable
+and _disable().
+
+Introduce a variable which controls whether xtermset_* are called and don't
+call them when ctrl-c is pressed - only call them when we're leaving jack.
+
+Debian #196429
+
+Depends on 40_enable_term.patch, and depends on the possible bogosity of
+40_enable_term.patch (see the note there).
+
+--- a/jack_term.py~ 2006-05-16 17:54:03.000000000 +0200
++++ b/jack_term.py 2006-05-16 17:54:32.000000000 +0200
+@@ -173,7 +173,7 @@
+ if (x, y) != (None, None):
+ size_x, size_y = x, y
+
+-def enable():
++def enable(all = 1):
+ global enabled
+
+ if not initialized:
+@@ -182,11 +182,12 @@
+ if enabled:
+ return
+
+- xtermset_enable()
++ if all:
++ xtermset_enable()
+ tmod.enable()
+ enabled = 1
+
+-def disable():
++def disable(all = 1):
+ global enabled
+ import os
+
+@@ -194,5 +195,6 @@
+ return
+
+ tmod.disable()
+- xtermset_disable()
++ if all:
++ xtermset_disable()
+ enabled = 0
+--- a/jack_display.py~ 2006-05-16 17:55:11.000000000 +0200
++++ b/jack_display.py 2006-05-16 17:55:05.000000000 +0200
+@@ -78,7 +78,10 @@
+ # be display problems.
+ sigint_handler = signal.getsignal(signal.SIGINT)
+ signal.signal(signal.SIGINT, signal.SIG_IGN)
+- jack_term.disable()
++ if sig:
++ jack_term.disable(all = 0)
++ else:
++ jack_term.disable(all = 1)
+
+ if sig:
+ exit_code = 2
+@@ -101,7 +104,7 @@
+ raw_input("press ENTER to exit\n")
+
+ if sig:
+- jack_term.enable()
++ jack_term.enable(all = 0)
+ signal.signal(signal.SIGINT, sigint_handler)
+
+ sys.exit(exit_code)
diff --git a/debian/patches/57_feedb_asciiletters.patch b/debian/patches/57_feedb_asciiletters.patch
new file mode 100644
index 0000000..855b5d3
--- /dev/null
+++ b/debian/patches/57_feedb_asciiletters.patch
@@ -0,0 +1,18 @@
+Now that we call call locale.setlocale() (see patch 78_setlocale.patch),
+string.letters will contain letters in the user's locale, which breaks
+jack. Just use ASCII instead for now. In the long run, all of this
+code probably needs to be rewritten.
+
+Debian bug #452097
+
+--- a/jack_freedb.py~ 2007-11-20 17:19:21.000000000 +0100
++++ b/jack_freedb.py 2007-11-20 17:22:27.000000000 +0100
+@@ -598,7 +598,7 @@
+ elif cf['_various']:
+ found = [[], [], [], [], [], []]
+ # lenght=3 2 1 , 3 2 1 (secondary)
+- ignore = string.letters + string.digits
++ ignore = string.ascii_letters + string.digits
+ titles = []
+ braces = [['"', '"'], ["'", "'"], ["(", ")"], ["[", "]"], ["{", "}"]]
+
diff --git a/debian/patches/58_progress_changed_error.patch b/debian/patches/58_progress_changed_error.patch
new file mode 100644
index 0000000..1116c63
--- /dev/null
+++ b/debian/patches/58_progress_changed_error.patch
@@ -0,0 +1,14 @@
+Don't fail when progress() has never been called before. Debian #295207.
+
+diff -urN jack-3.1.1~/jack_functions.py jack-3.1.1/jack_functions.py
+--- jack-3.1.1~/jack_functions.py 2005-06-20 17:07:52.237610968 +0100
++++ jack-3.1.1/jack_functions.py 2005-06-20 17:08:07.111349816 +0100
+@@ -33,6 +33,8 @@
+
+ from jack_globals import *
+
++progress_changed = 0
++
+ def df(fs = ".", blocksize = 1024):
+ "returns free space on a filesystem (in bytes)"
+ try:
diff --git a/debian/patches/59_assume_ok_query.patch b/debian/patches/59_assume_ok_query.patch
new file mode 100644
index 0000000..a0c4f77
--- /dev/null
+++ b/debian/patches/59_assume_ok_query.patch
@@ -0,0 +1,33 @@
+Under some circumstances we want to tag tracks even when the FreeDB query
+failed: it's possible that the user manually added the jack.freedb file.
+Therefore, check whether parsing the FreeDB file works.
+
+Debian bug #441270
+
+Depends on 53_no_tag_when_freedb_fails.patch
+
+--- a/jack_prepare.py 2007-10-27 22:50:40.000000000 +0200
++++ b/jack_prepare.py 2007-10-27 22:52:58.000000000 +0200
+@@ -507,7 +507,6 @@
+ if not x or x[0].upper() != "Y":
+ sys.exit(0)
+ cf['_query_on_start'] = 0
+- cf['_set_id3tag'] = 0
+ else:
+ jack_display.exit()
+
+@@ -546,6 +545,14 @@
+ error("query on start failed to give a good freedb file, aborting.")
+ else:
+ err, jack_tag.track_names, jack_tag.locale_names, freedb_rename, revision = jack_freedb.interpret_db_file(jack_ripstuff.all_tracks, todo, cf['_freedb_form_file'], verb = cf['_query_on_start'], warn = cf['_query_on_start'])
++ # If the FreeDB query failed and the FreeDB data cannot be parsed,
++ # don't tag the files. However, if the FreeDB data can be parsed
++ # even though the query failed assume that the query worked and
++ # do the tagging (the user might have edited the file by hand).
++ if cf['_cont_failed_query'] and err:
++ cf['_set_id3tag'] = 0
++ else:
++ cf['_query_on_start'] = 1
+ return freedb_rename
+
+ def undo_rename(status, todo):
diff --git a/debian/patches/60_ask_edit_freedb_when_query_fails.patch b/debian/patches/60_ask_edit_freedb_when_query_fails.patch
new file mode 100644
index 0000000..8dc9c25
--- /dev/null
+++ b/debian/patches/60_ask_edit_freedb_when_query_fails.patch
@@ -0,0 +1,19 @@
+Ask users whether they want to edit the FreeDB data manually when the
+FreeDB query fails.
+
+--- a/jack_prepare.py 2007-10-27 22:53:13.000000000 +0200
++++ b/jack_prepare.py 2007-10-27 22:53:35.000000000 +0200
+@@ -506,7 +506,12 @@
+ x = raw_input("\nfreedb search failed, continue? (y/N) ") + "x"
+ if not x or x[0].upper() != "Y":
+ sys.exit(0)
+- cf['_query_on_start'] = 0
++ if not cf['_edit_freedb']:
++ x = raw_input("\nDo you want to edit the freedb data? (y/N) ") + "x"
++ if x and x[0].upper() == "Y":
++ cf['_edit_freedb'] = 1
++ else:
++ cf['_query_on_start'] = 0
+ else:
+ jack_display.exit()
+
diff --git a/debian/patches/61_pymem_del.patch b/debian/patches/61_pymem_del.patch
new file mode 100644
index 0000000..7fbe913
--- /dev/null
+++ b/debian/patches/61_pymem_del.patch
@@ -0,0 +1,27 @@
+The C API requires using the same memory API for a given memory block,
+which will show up as a segfault, at least in python2.5. See
+http://bugs.debian.org/468972
+
+Fix by Barry deFreese <bddebian@comcast.net> and Thomas Viehmann <tv@beamnet.de>
+
+diff -Nur jack-3.1.1+cvs20050801/cursesmodule/jack_cursesmodule.c jack-3.1.1+cvs20050801.new/cursesmodule/jack_cursesmodule.c
+--- jack-3.1.1+cvs20050801/cursesmodule/jack_cursesmodule.c 2006-02-05 09:09:07.000000000 -0500
++++ jack-3.1.1+cvs20050801.new/cursesmodule/jack_cursesmodule.c 2008-03-05 22:46:41.000000000 -0500
+@@ -259,7 +259,7 @@
+ {
+ PyCursesWindowObject *wo;
+
+- wo = PyObject_NEW(PyCursesWindowObject, &PyCursesWindow_Type);
++ wo = PyObject_New(PyCursesWindowObject, &PyCursesWindow_Type);
+ if (wo == NULL) return NULL;
+ wo->win = win;
+ return (PyObject *)wo;
+@@ -270,7 +270,7 @@
+ PyCursesWindowObject *wo;
+ {
+ if (wo->win != stdscr) delwin(wo->win);
+- PyMem_DEL(wo);
++ PyObject_Del(wo);
+ }
+
+ /* Addch, Addstr, Addnstr */
diff --git a/debian/patches/62_dont_repeat_inexact.patch b/debian/patches/62_dont_repeat_inexact.patch
new file mode 100644
index 0000000..79f879c
--- /dev/null
+++ b/debian/patches/62_dont_repeat_inexact.patch
@@ -0,0 +1,39 @@
+Don't print a warning that the calculated ID and that from FreeDB don't
+match when we had an inexact match. Debian #304744.
+
+diff -urN a/jack_freedb.py jack-3.1.1+cvs20050801/jack_freedb.py
+--- a/jack_freedb.py 2006-02-05 15:54:03.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_freedb.py 2006-02-05 16:51:59.000000000 +0000
+@@ -37,6 +37,7 @@
+ names_available = None # freedb info is available
+ dir_created = None # dirs are only renamed if we have created them
+ NUM, LEN, START, COPY, PRE, CH, RIP, RATE, NAME = range(9)
++freedb_inexact_match = -1
+
+ freedb_servers = {
+ 'freedb': {
+@@ -234,6 +235,9 @@
+ buf = f.readline()
+ if buf and buf[0:1] == "2":
+ if buf[0:3] in ("210", "211"): # Found inexact or multiple exact matches, list follows
++ if buf[0:3] == "211":
++ global freedb_inexact_match
++ freedb_inexact_match = 1
+ print "Found the following matches. Choose one:"
+ num = 1
+ matches = []
+@@ -385,10 +389,10 @@
+ for i in read_ids:
+ if i == cd_id:
+ id_matched = 1
+- if not id_matched and warn:
+- print "Warning: calculated id (" + cd_id + ") and id from freedb file"
+- print " :", read_ids
+- print " : do not match, hopefully due to inexact match."
++ if not id_matched and warn and freedb_inexact_match < 1:
++ print "Warning: CD signature ID and ID from FreeDB file do not match."
++ print " CD signature: " + cd_id
++ print " FreeDB ID: " + ",".join(read_ids)
+ for i in read_ids:
+ for j in i:
+ if j not in "0123456789abcdef":
diff --git a/debian/patches/63_date_unicode.patch b/debian/patches/63_date_unicode.patch
new file mode 100644
index 0000000..7082577
--- /dev/null
+++ b/debian/patches/63_date_unicode.patch
@@ -0,0 +1,14 @@
+Fixes a bug when strftime returns UTF-8 because of the locale name.
+http://bugs.debian.org/471843
+
+--- a/jack~ 2008-03-21 16:03:07.000000000 +0100
++++ b/jack 2008-03-21 16:07:00.000000000 +0100
+@@ -277,7 +277,7 @@
+ jack_tag.tag(freedb_rename)
+
+ if jack_functions.progress_changed:
+- jack_functions.progress("all", "done", time.strftime("%b %2d %H:%M:%S", time.localtime(time.time())))
++ jack_functions.progress("all", "done", unicode(time.strftime("%b %2d %H:%M:%S", time.localtime(time.time())), locale.getpreferredencoding(), "replace"))
+
+ if cf['_remove_files']:
+ print "cleaning up in", os.getcwd()
diff --git a/debian/patches/64_catch_id3_error.patch b/debian/patches/64_catch_id3_error.patch
new file mode 100644
index 0000000..f4d1291
--- /dev/null
+++ b/debian/patches/64_catch_id3_error.patch
@@ -0,0 +1,29 @@
+eyeD3 only accepts years that have 4 digits; catch the exception in case
+the year contains something else. Debian bug http://bugs.debian.org/478784
+
+--- a/jack_tag.py 2008-05-04 16:28:14.000000000 +0200
++++ b/jack_tag.py 2008-05-04 16:38:50.000000000 +0200
+@@ -112,7 +112,10 @@
+ if cf['_id3_genre'] != -1:
+ tag.setGenre("(%d)" % (cf['_id3_genre']))
+ if cf['_id3_year'] != -1:
+- tag.setDate(cf['_id3_year'])
++ try:
++ tag.setDate(cf['_id3_year'])
++ except eyeD3.tag.TagException, e:
++ print "Error tagging file: %s" % e
+ tag.setPlayCount(int(i[LEN] * 1000.0 / 75 + 0.5))
+ tag.update()
+ mp3file.close()
+@@ -139,7 +142,10 @@
+ elif old_genre == None:
+ tag.setGenre("(255)") # unknown
+ if cf['_id3_year'] != -1:
+- tag.setDate(cf['_id3_year'])
++ try:
++ tag.setDate(cf['_id3_year'])
++ except eyeD3.tag.TagException, e:
++ print "Error tagging file: %s" % e
+ try:
+ tag.update()
+ except UnicodeEncodeError:
diff --git a/debian/patches/66_rename_unicode.patch b/debian/patches/66_rename_unicode.patch
new file mode 100644
index 0000000..ce86002
--- /dev/null
+++ b/debian/patches/66_rename_unicode.patch
@@ -0,0 +1,19 @@
+When renaming directories, make sure both the old and the new dir are
+Unicode strings; also make this more robust; see Debian #338816 and
+#339879.
+
+
+Depends on 60_utf8_support.patch
+
+diff -urN jack-3.1.1~/jack_freedb.py jack-3.1.1/jack_freedb.py
+--- jack-3.1.1~/jack_freedb.py 2005-12-01 01:03:55.000000000 +0000
++++ jack-3.1.1/jack_freedb.py 2005-12-01 01:06:20.000000000 +0000
+@@ -84,7 +84,7 @@
+ if jack_utils.check_path(dirs_created, old_dirs) and not jack_utils.check_path(dirs_created, new_dirs):
+ jack_utils.rename_path(dirs_created, new_dirs)
+ print "Info: cwd now", os.getcwd()
+- jack_functions.progress("all", 'ren', dir_created + "-->" + unicode(new_dir, cf['_charset']))
++ jack_functions.progress("all", 'ren', unicode(dir_created + "-->" + new_dir, cf['_charset'], "replace"))
+
+ if not err:
+ names_available = 1
diff --git a/debian/patches/67_progress_utf8_vs_filenames.patch b/debian/patches/67_progress_utf8_vs_filenames.patch
new file mode 100644
index 0000000..a367590
--- /dev/null
+++ b/debian/patches/67_progress_utf8_vs_filenames.patch
@@ -0,0 +1,16 @@
+Even though jack.progress is always UTF-8 encoded, use the local encoding
+for filenames mentioned in jack.progress, otherwise jack thinks it has to
+rip/encode files again which already exist. Debian #338816.
+
+diff -urN jack-3.1.1~/jack_prepare.py jack-3.1.1/jack_prepare.py
+--- jack-3.1.1~/jack_prepare.py 2005-12-01 01:03:55.000000000 +0000
++++ jack-3.1.1/jack_prepare.py 2005-12-01 01:48:56.000000000 +0000
+@@ -403,7 +403,7 @@
+ if status[i]['names'][-1] == names[0]:
+ status[i]['names'].append(names[1])
+ if type(i) == types.IntType:
+- tracknum[i][NAME] = status[i]['names'][-1]
++ tracknum[i][NAME] = unicode(status[i]['names'][-1], "utf-8", "replace").encode(cf['_charset'], "replace")
+ del status[i]['ren']
+
+ # status info for the whole CD is treated separately
diff --git a/debian/patches/68_support_high_char_renames.patch b/debian/patches/68_support_high_char_renames.patch
new file mode 100644
index 0000000..15d16bb
--- /dev/null
+++ b/debian/patches/68_support_high_char_renames.patch
@@ -0,0 +1,21 @@
+Allow characters >128 in unusable_chars and replacement_chars.
+Debian #339879.
+
+--- a/jack_tag.py~ 2005-11-19 14:47:23.000000000 +0000
++++ b/jack_tag.py 2005-11-19 15:06:54.000000000 +0000
+@@ -202,7 +202,13 @@
+ newname = jack_misc.multi_replace(cf['_rename_fmt'], replacelist)
+ exec("newname = newname" + cf['_char_filter'])
+ for char_i in range(len(cf['_unusable_chars'])):
+- newname = string.replace(newname, cf['_unusable_chars'][char_i], cf['_replacement_chars'][char_i])
++ try:
++ a = unicode(cf['_unusable_chars'][char_i], locale.getpreferredencoding(), "replace")
++ b = unicode(cf['_replacement_chars'][char_i], locale.getpreferredencoding(), "replace")
++ except UnicodeDecodeError:
++ warning("Cannot substitute unusable character %d." % (char_i+1))
++ else:
++ newname = string.replace(newname, a, b)
+ try:
+ i[NAME] = unicode(i[NAME], "utf-8")
+ except UnicodeDecodeError:
+
diff --git a/debian/patches/69_document_freedb_dir.patch b/debian/patches/69_document_freedb_dir.patch
new file mode 100644
index 0000000..32f51da
--- /dev/null
+++ b/debian/patches/69_document_freedb_dir.patch
@@ -0,0 +1,19 @@
+Document freedb_dir since this doesn't show up with --longhelp.
+See http://bugs.debian.org/458384
+
+--- a/jack.man 2008-03-09 10:53:21.000000000 +0100
++++ b/jack.man 2008-03-09 10:56:50.000000000 +0100
+@@ -423,6 +423,13 @@
+ .TP
+ .B \-\-write-m3u
+ create a playlist in .m3u format. This has bugs, don't rely on it.
++.SH CONFIG FILE OPTIONS
++In addition the the command line options, there are some options that
++can only be set directly in the config file.
++.TP
++.B freedb_dir
++all FreeDB queries will be done in this (local) directory; failed local
++queries will be done via the network. Example: /var/spool/freedb
+ .SH EXAMPLES
+ Insert a CD, fire up jack:
+ .RS
diff --git a/debian/patches/70_fix_upd_progress.patch b/debian/patches/70_fix_upd_progress.patch
new file mode 100644
index 0000000..0f35ebe
--- /dev/null
+++ b/debian/patches/70_fix_upd_progress.patch
@@ -0,0 +1,76 @@
+Fix the --upd-progress function which dies with the following
+traceback. Debian #351453
+
+> 11510:tbm@derision: ~/tmp/jack/jack-1210f412] jack --upd-progress
+> This is jack 3.1.1 (C)2004 Arne Zellentin <zarne@users.sf.net>
+> Traceback (most recent call last):
+> File "/usr/bin/jack", line 136, in ?
+> jack_prepare.update_progress(todo)
+> File "/usr/lib/python2.3/site-packages/jack_prepare.py", line 341, in update_progress
+> if not status[num]['dae']:
+> NameError: global name 'status' is not defined
+
+(and when this is fixed, dies because the ogg modules is not loaded)
+
+
+Depends on 33_flac_mutagen.patch
+
+
+diff -urN jack-3.1.1+cvs20050801~/jack jack-3.1.1+cvs20050801/jack
+--- jack-3.1.1+cvs20050801~/jack 2006-02-13 21:49:58.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack 2006-02-13 23:45:35.000000000 +0000
+@@ -132,7 +132,7 @@
+
+ ### (6) update progress file at user's request (operation mode)
+ if cf['_upd_progress']:
+- jack_prepare.update_progress(todo)
++ jack_prepare.update_progress(status, todo)
+ sys.exit(0)
+
+ ### (7) now read in the progress file
+diff -urN jack-3.1.1+cvs20050801~/jack_init.py jack-3.1.1+cvs20050801/jack_init.py
+--- jack-3.1.1+cvs20050801~/jack_init.py 2006-02-13 21:49:58.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_init.py 2006-02-13 23:46:31.000000000 +0000
+@@ -56,10 +56,8 @@
+ try:
+ import ogg.vorbis
+ except:
+- class dummy_ogg:
+- def __init__(self):
+- warning("ogg module not installed, ogg support disabled")
+- ogg = dummy_ogg()
++ warning("ogg module not installed, ogg support disabled")
++ ogg = None
+
+ try:
+ import mutagen.flac as flac
+diff -urN jack-3.1.1+cvs20050801~/jack_prepare.py jack-3.1.1+cvs20050801/jack_prepare.py
+--- jack-3.1.1+cvs20050801~/jack_prepare.py 2006-02-13 21:49:58.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_prepare.py 2006-02-13 23:45:55.000000000 +0000
+@@ -37,6 +37,7 @@
+ import jack_tag
+
+ from jack_globals import *
++from jack_init import ogg
+
+ tracknum = None
+ datatracks = []
+@@ -326,7 +327,7 @@
+ status['all']['id3_year'] = ["-1",]
+ return status
+
+-def update_progress(todo):
++def update_progress(status, todo):
+ ext = jack_targets.targets[jack_helpers.helpers[cf['_encoder']]['target']]['file_extension']
+ "update progress file at user's request (operation mode)"
+
+@@ -342,7 +343,7 @@
+ if ext == ".mp3":
+ x = jack_mp3.mp3format(i[NAME] + ext)
+ temp_rate = x['bitrate']
+- elif ext == ".ogg":
++ elif ext == ".ogg" and ogg:
+ x = ogg.vorbis.VorbisFile(i[NAME] + ext)
+ temp_rate = int(x.raw_total(0) * 8 / x.time_total(0) / 1000 + 0.5)
+ else:
+
diff --git a/debian/patches/71_freedb_filename_cleanup.patch b/debian/patches/71_freedb_filename_cleanup.patch
new file mode 100644
index 0000000..0efe986
--- /dev/null
+++ b/debian/patches/71_freedb_filename_cleanup.patch
@@ -0,0 +1,90 @@
+Code clean-up (needed for future functionality): move the generation of
+filenames based on FreeDB information into jack_freedb.py.
+
+Depends on 62_dont_repeat_inexact.patch, 66_rename_unicode.patch and
+68_support_high_char_renames.patch and 27_allow_year_genre_sa.patch.
+
+diff -urN jack-3.1.1~/jack_freedb.py jack-3.1.1/jack_freedb.py
+--- jack-3.1.1~/jack_freedb.py 2006-02-05 03:58:48.000000000 +0000
++++ jack-3.1.1/jack_freedb.py 2006-02-05 05:41:16.000000000 +0000
+@@ -30,6 +30,8 @@
+ import jack_functions
+ import jack_progress
+ import jack_utils
++import jack_tag
++import jack_misc
+
+ from jack_version import prog_version, prog_name
+ from jack_globals import *
+@@ -38,6 +40,7 @@
+ dir_created = None # dirs are only renamed if we have created them
+ NUM, LEN, START, COPY, PRE, CH, RIP, RATE, NAME = range(9)
+ freedb_inexact_match = -1
++filenames = []
+
+ freedb_servers = {
+ 'freedb': {
+@@ -87,6 +90,36 @@
+ jack_functions.progress("all", 'ren', unicode(dir_created + "-->" + new_dir, cf['_charset'], "replace"))
+
+ if not err:
++ cd = track_names[0]
++ year = genretxt = None
++ if len(cd) > 2:
++ year = `cd[2]`
++ if len(cd) > 3:
++ genretxt = id3genres[cd[3]]
++ filenames.append('') # FIXME: possibly put the dir here, but in no
++ # case remove this since people access filenames with i[NUM] which starts at 1
++ num = 1
++ for i in track_names[1:]:
++ replacelist = [("%n", cf['_rename_num'] % num), ("%l", cd[1]), ("%t", i[1]),
++ ("%y", year), ("%g", genretxt)]
++ if cf['_various']:
++ replacelist.append(("%a", i[0]))
++ newname = jack_misc.multi_replace(cf['_rename_fmt_va'], replacelist)
++ else:
++ replacelist.append(("%a", cd[0]))
++ newname = jack_misc.multi_replace(cf['_rename_fmt'], replacelist)
++ exec("newname = newname" + cf['_char_filter'])
++ for char_i in range(len(cf['_unusable_chars'])):
++ try:
++ a = unicode(cf['_unusable_chars'][char_i], locale.getpreferredencoding(), "replace")
++ b = unicode(cf['_replacement_chars'][char_i], locale.getpreferredencoding(), "replace")
++ except UnicodeDecodeError:
++ warning("Cannot substitute unusable character %d."
++% (char_i+1))
++ else:
++ newname = string.replace(newname, a, b)
++ filenames.append(newname)
++ num += 1
+ names_available = 1
+ else:
+ freedb_rename = 0
+diff -urN jack-3.1.1~/jack_tag.py jack-3.1.1/jack_tag.py
+--- jack-3.1.1~/jack_tag.py 2006-02-05 05:40:23.000000000 +0000
++++ jack-3.1.1/jack_tag.py 2006-02-05 05:40:28.000000000 +0000
+@@ -193,22 +193,7 @@
+ oggi.add_tag('DATE', `cf['_id3_year']`)
+ oggi.write_to(mp3name)
+ if freedb_rename:
+- if t_artist: # 'Various Artists'
+- replacelist = (("%n", cf['_rename_num'] % i[NUM]), ("%a", t_artist), ("%t", t_name), ("%l", a_title), ("%y", `cf['_id3_year']`), ("%g", genretxt))
+- newname = jack_misc.multi_replace(cf['_rename_fmt_va'], replacelist)
+-
+- else:
+- replacelist = (("%n", cf['_rename_num'] % i[NUM]), ("%a", a_artist), ("%t", t_name), ("%l", a_title), ("%y", `cf['_id3_year']`), ("%g", genretxt))
+- newname = jack_misc.multi_replace(cf['_rename_fmt'], replacelist)
+- exec("newname = newname" + cf['_char_filter'])
+- for char_i in range(len(cf['_unusable_chars'])):
+- try:
+- a = unicode(cf['_unusable_chars'][char_i], locale.getpreferredencoding(), "replace")
+- b = unicode(cf['_replacement_chars'][char_i], locale.getpreferredencoding(), "replace")
+- except UnicodeDecodeError:
+- warning("Cannot substitute unusable character %d." % (char_i+1))
+- else:
+- newname = string.replace(newname, a, b)
++ newname = jack_freedb.filenames[i[NUM]]
+ try:
+ i[NAME] = unicode(i[NAME], "utf-8")
+ except UnicodeDecodeError:
diff --git a/debian/patches/72_upd_progress_renamed.patch b/debian/patches/72_upd_progress_renamed.patch
new file mode 100644
index 0000000..a28c7f2
--- /dev/null
+++ b/debian/patches/72_upd_progress_renamed.patch
@@ -0,0 +1,72 @@
+Make --upd-progress work even after files have been renamed by
+looking for both the generic and the FreeDB based name. Debian #351460
+
+Depends on 71_freedb_filename_cleanup.patch.
+
+diff -urN a/jack_functions.py jack-3.1.1+cvs20050801/jack_functions.py
+--- a/jack_functions.py 2006-02-05 15:54:03.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_functions.py 2006-02-05 16:24:54.000000000 +0000
+@@ -24,6 +24,7 @@
+ import string
+ import sys
+ import os
++import locale
+
+ import jack_TOCentry
+ import jack_CDTime
+@@ -31,6 +32,7 @@
+ import jack_TOC
+ import jack_mp3
+ import jack_helpers
++import jack_freedb
+
+ from jack_globals import *
+
+@@ -461,3 +463,14 @@
+
+ import jack_version
+ error("illegal genre. Try '" + jack_version.prog_name + " --id3-genre help' for a list.")
++
++def check_file(num, i, ext):
++ "Check if a song exists, either with a generic name or with the FreeDB name"
++ if os.path.exists(i[NAME] + ext):
++ return i[NAME]
++ elif jack_freedb.names_available:
++ s = jack_freedb.filenames[num].encode(locale.getpreferredencoding(), "replace")
++ if os.path.exists(s + ext):
++ return s
++ return None
++
+diff -urN a/jack_prepare.py jack-3.1.1+cvs20050801/jack_prepare.py
+--- a/jack_prepare.py 2006-02-05 15:54:03.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_prepare.py 2006-02-05 16:24:34.000000000 +0000
+@@ -331,19 +331,25 @@
+ "update progress file at user's request (operation mode)"
+
+ if cf['_upd_progress']:
++ # users may still have a valid jack.freedb file lying around
++ if not jack_freedb.names_available:
++ err, jack_tag.track_names, jack_tag.locale_names, freedb_rename, revision = jack_freedb.interpret_db_file(jack_ripstuff.all_tracks, todo, cf['_freedb_form_file'], verb = 0, dirs = 1)
++
+ for i in todo:
+ num = i[NUM]
+ if not status[num]['dae']:
+- if os.path.exists(i[NAME] + ".wav"):
++ filename = jack_functions.check_file(num, i, ".wav")
++ if filename:
+ status[num]['dae'] = " * [ simulated ]"
+ jack_functions.progress(num, "dae", status[num]['dae'])
+ if not status[num]['enc']:
+- if os.path.exists(i[NAME] + ext):
++ filename = jack_functions.check_file(num, i, ext)
++ if filename:
+ if ext == ".mp3":
+- x = jack_mp3.mp3format(i[NAME] + ext)
++ x = jack_mp3.mp3format(filename + ext)
+ temp_rate = x['bitrate']
+ elif ext == ".ogg" and ogg:
+- x = ogg.vorbis.VorbisFile(i[NAME] + ext)
++ x = ogg.vorbis.VorbisFile(filename + ext)
+ temp_rate = int(x.raw_total(0) * 8 / x.time_total(0) / 1000 + 0.5)
+ else:
+ error("don't know how to handle %s files." % ext)
diff --git a/debian/patches/73_err_unknown_sub.patch b/debian/patches/73_err_unknown_sub.patch
new file mode 100644
index 0000000..6608750
--- /dev/null
+++ b/debian/patches/73_err_unknown_sub.patch
@@ -0,0 +1,98 @@
+Print an error if the information for dir_template (or rename_ftm*) cannot
+be filled in. Debian #349368.
+
+Depends on 71_freedb_filename_cleanup.patch.
+
+diff -urN d/jack_freedb.py jack-3.1.1+cvs20050801/jack_freedb.py
+--- d/jack_freedb.py 2006-02-06 22:51:54.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_freedb.py 2006-02-06 22:52:01.000000000 +0000
+@@ -104,10 +104,10 @@
+ ("%y", year), ("%g", genretxt)]
+ if cf['_various']:
+ replacelist.append(("%a", i[0]))
+- newname = jack_misc.multi_replace(cf['_rename_fmt_va'], replacelist)
++ newname = jack_misc.multi_replace(cf['_rename_fmt_va'], replacelist, "rename_fmt_va", warn = (num == 1))
+ else:
+ replacelist.append(("%a", cd[0]))
+- newname = jack_misc.multi_replace(cf['_rename_fmt'], replacelist)
++ newname = jack_misc.multi_replace(cf['_rename_fmt'], replacelist, "rename_fmt", warn = (num == 1))
+ exec("newname = newname" + cf['_char_filter'])
+ for char_i in range(len(cf['_unusable_chars'])):
+ try:
+diff -urN d/jack_misc.py jack-3.1.1+cvs20050801/jack_misc.py
+--- d/jack_misc.py 2006-02-06 22:51:54.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_misc.py 2006-02-06 22:52:01.000000000 +0000
+@@ -20,11 +20,19 @@
+ import sys
+ import os
+
++import jack_globals
++
+ def id(x):
+ return x
+
+-def multi_replace(s, rules, filter = id):
++def multi_replace(s, rules, where, filter = id, warn = 0):
+ "like string.replace but take list (('from0', 'to0'), ('from1', 'to1'))..."
++
++ if warn == 2:
++ do_warn = jack_globals.error
++ else:
++ do_warn = jack_globals.warning
++
+ # currently all from must be like %x (a percent sign follow by single char.
+ res = ""
+ maybe = 0
+@@ -34,10 +42,14 @@
+ found = 0
+ for j in rules:
+ if ("%" + i) == j[0]:
++ if not j[1] and warn:
++ do_warn("%%%c is not set but used in %s." % (i, where))
+ res = res[:-1] + filter(j[1])
+ found = 1
+ if found:
+ continue
++ elif warn:
++ do_warn("Unknown pattern %%%c is used in %s." % (i, where))
+ maybe = 0
+ if i == "%":
+ maybe = 1
+diff -urN d/jack_utils.py jack-3.1.1+cvs20050801/jack_utils.py
+--- d/jack_utils.py 2006-02-06 22:51:54.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_utils.py 2006-02-06 22:54:21.000000000 +0000
+@@ -27,6 +27,7 @@
+ import jack_globals
+ import jack_misc
+ import jack_term
++import jack_config
+
+ from jack_globals import *
+
+@@ -170,15 +171,19 @@
+ dirs = template.split(os.path.sep)
+
+ dirs2 = []
++ if cf['_id3_year'] > 0:
++ year = `cf['_id3_year']`
++ else:
++ year = None
++ replace_list = (("%a", names[0][0].encode(cf['_charset'], "replace")),
++ ("%l", names[0][1].encode(cf['_charset'], "replace")),
++ ("%y", year), ("%g", cf['_id3_genre_txt']))
+ for i in dirs:
+- replace_list = (("%a", names[0][0].encode(cf['_charset'], "replace")),
+- ("%l", names[0][1].encode(cf['_charset'], "replace")),
+- ("%y", `cf['_id3_year']`), ("%g", cf['_id3_genre_txt']))
+- x = jack_misc.multi_replace(i, replace_list, unusable_charmap)
++ x = jack_misc.multi_replace(i, replace_list, "dir_template", unusable_charmap, warn = 2)
+ exec("x = x" + cf['_char_filter'])
+ dirs2.append(x)
+- if cf['_append_year'] and len(`cf['_id3_year']`) == 4: # Y10K bug!
+- dirs2[-1] = dirs2[-1] + jack_misc.multi_replace(cf['_append_year'], replace_list)
++ if cf['_append_year'] and year:
++ dirs2[-1] = dirs2[-1] + jack_misc.multi_replace(cf['_append_year'], replace_list, "append-year", warn = 1)
+ name = ""
+ for i in dirs2:
+ name = os.path.join(name, i)
+
diff --git a/debian/patches/74_multi_replace_cleanup.patch b/debian/patches/74_multi_replace_cleanup.patch
new file mode 100644
index 0000000..d4a6c46
--- /dev/null
+++ b/debian/patches/74_multi_replace_cleanup.patch
@@ -0,0 +1,94 @@
+Code clean-up: make jack_misc.multi_replace() readable.
+
+Depends on 73_err_unknown_sub.patch
+
+diff -urN e/jack_freedb.py jack-3.1.1+cvs20050801/jack_freedb.py
+--- e/jack_freedb.py 2006-02-06 22:55:33.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_freedb.py 2006-02-06 22:55:45.000000000 +0000
+@@ -100,13 +100,13 @@
+ # case remove this since people access filenames with i[NUM] which starts at 1
+ num = 1
+ for i in track_names[1:]:
+- replacelist = [("%n", cf['_rename_num'] % num), ("%l", cd[1]), ("%t", i[1]),
+- ("%y", year), ("%g", genretxt)]
++ replacelist = {"n": cf['_rename_num'] % num, "l": cd[1], "t": i[1],
++ "y": year, "g": genretxt}
+ if cf['_various']:
+- replacelist.append(("%a", i[0]))
++ replacelist["a"] = i[0]
+ newname = jack_misc.multi_replace(cf['_rename_fmt_va'], replacelist, "rename_fmt_va", warn = (num == 1))
+ else:
+- replacelist.append(("%a", cd[0]))
++ replacelist["a"] = cd[0]
+ newname = jack_misc.multi_replace(cf['_rename_fmt'], replacelist, "rename_fmt", warn = (num == 1))
+ exec("newname = newname" + cf['_char_filter'])
+ for char_i in range(len(cf['_unusable_chars'])):
+diff -urN e/jack_misc.py jack-3.1.1+cvs20050801/jack_misc.py
+--- e/jack_misc.py 2006-02-06 22:55:33.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_misc.py 2006-02-06 22:55:45.000000000 +0000
+@@ -33,28 +33,18 @@
+ else:
+ do_warn = jack_globals.warning
+
+- # currently all from must be like %x (a percent sign follow by single char.
+- res = ""
+- maybe = 0
+- for i in s:
+- if maybe:
+- maybe = 0
+- found = 0
+- for j in rules:
+- if ("%" + i) == j[0]:
+- if not j[1] and warn:
+- do_warn("%%%c is not set but used in %s." % (i, where))
+- res = res[:-1] + filter(j[1])
+- found = 1
+- if found:
+- continue
+- elif warn:
+- do_warn("Unknown pattern %%%c is used in %s." % (i, where))
+- maybe = 0
+- if i == "%":
+- maybe = 1
+- res = res + i
+- return res
++ # get a list of characters we need to replace (i.e. the x from %x)
++ # currently all from must be like %x (a percent sign follow by single char).
++ pattern = [x[0] for x in s[s.find("%"):].split("%") if x]
++ for p in pattern:
++ if not rules.has_key(p):
++ warn and do_warn("Unknown pattern %%%c is used in %s." % (p, where))
++ else:
++ if not rules[p]:
++ warn and do_warn("%%%c is not set but used in %s." % (p, where))
++ else:
++ s = s.replace("%%%c" % p, filter(rules[p]))
++ return s
+
+ def safe_int(number, message):
+ try:
+diff -urN e/jack_utils.py jack-3.1.1+cvs20050801/jack_utils.py
+--- e/jack_utils.py 2006-02-06 22:55:34.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_utils.py 2006-02-06 22:56:48.000000000 +0000
+@@ -175,15 +175,15 @@
+ year = `cf['_id3_year']`
+ else:
+ year = None
+- replace_list = (("%a", names[0][0].encode(cf['_charset'], "replace")),
+- ("%l", names[0][1].encode(cf['_charset'], "replace")),
+- ("%y", year), ("%g", cf['_id3_genre_txt']))
++ replacelist = {"a": names[0][0].encode(cf['_charset'], "replace"),
++ "l": names[0][1].encode(cf['_charset'], "replace"),
++ "y": year, "g": cf['_id3_genre_txt']}
+ for i in dirs:
+- x = jack_misc.multi_replace(i, replace_list, "dir_template", unusable_charmap, warn = 2)
++ x = jack_misc.multi_replace(i, replacelist, "dir_template", unusable_charmap, warn = 2)
+ exec("x = x" + cf['_char_filter'])
+ dirs2.append(x)
+ if cf['_append_year'] and year:
+- dirs2[-1] = dirs2[-1] + jack_misc.multi_replace(cf['_append_year'], replace_list, "append-year", warn = 1)
++ dirs2[-1] = dirs2[-1] + jack_misc.multi_replace(cf['_append_year'], replacelist, "append-year", warn = 1)
+ name = ""
+ for i in dirs2:
+ name = os.path.join(name, i)
+
diff --git a/debian/patches/75_fix_datatrack_rename.patch b/debian/patches/75_fix_datatrack_rename.patch
new file mode 100644
index 0000000..da1edb0
--- /dev/null
+++ b/debian/patches/75_fix_datatrack_rename.patch
@@ -0,0 +1,177 @@
+Fixes that "jack -R -t x" fails when x is a data track and CD not in drive.
+jack doesn't realize that it is in fact a data track. We can fix this by
+moving the code around a bit so the jack.progress file is parsed first,
+then jack will know it's not a valid audio track. Debian #341889
+
+Depends on 70_fix_upd_progress.patch.
+
+
+diff -urN c/jack jack-3.1.1+cvs20050801/jack
+--- c/jack 2006-02-05 18:48:20.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack 2006-02-05 19:04:29.000000000 +0000
+@@ -94,36 +94,28 @@
+
+ ext = jack_targets.targets[jack_helpers.helpers[cf['_encoder']]['target']]['file_extension']
+
+-### (1) search for a dir containing a toc-file or do the multi-mode
++### search for a dir containing a toc-file or do the multi-mode
+ toc_just_read = jack_prepare.find_workdir()
+ os.environ["JACK_CUR_DIR"] = os.getcwd()
+ os.environ["JACK_BASE_DIR"] = cf['_base_dir']
+ # now we are set to go as we know we are in the right dir
+
+-### (2) check toc (operation mode)
++### check toc (operation mode)
+ if cf['_check_toc']:
+ jack_prepare.check_toc()
+ sys.exit(0)
+
+-### (3a) read and interpret toc_file
++### read and interpret toc_file
+ is_submittable, track1_offset = jack_prepare.read_toc_file()
+
+-### (3b) make sure we have a freedb file
++### make sure we have a freedb file
+ if not os.path.exists(cf['_freedb_form_file']):
+ jack_freedb.freedb_template(jack_ripstuff.all_tracks)
+
+-### (4a) filter out data tracks
+-jack_prepare.filter_tracks(toc_just_read)
+-
+-### (4b) Parse tracks from argv, generate todo
+-todo = jack_prepare.gen_todo()
+-if len(todo) == 0:
+- error("nothing to do. bye.")
+-
+ ### init status
+-jack_status.init(todo)
++jack_status.init(jack_ripstuff.all_tracks)
+
+-#XXX## (5) read progress info into status
++#XXX## read progress info into status
+
+ jack_ripstuff.all_tracks_orig = []
+ for i in jack_ripstuff.all_tracks:
+@@ -131,20 +123,27 @@
+
+ status = jack_prepare.init_status()
+
+-### (6) update progress file at user's request (operation mode)
+-if cf['_upd_progress']:
+- jack_prepare.update_progress(status, todo)
+- sys.exit(0)
++jack_prepare.tracknum = {}
++for i in jack_ripstuff.all_tracks:
++ jack_prepare.tracknum[i[NUM]] = i
+
+-### (7) now read in the progress file
+-status = jack_prepare.read_progress(status, todo)
++### now read in the progress file
++status = jack_prepare.read_progress(status, jack_ripstuff.all_tracks)
+
+-### (8) submit freedb data on user's request
++### filter out data tracks
++jack_prepare.filter_tracks(toc_just_read, status)
++
++### Parse tracks from argv, generate todo
++todo = jack_prepare.gen_todo()
++if len(todo) == 0:
++ error("nothing to do. bye.")
++
++### submit freedb data on user's request
+ if cf['_freedb_submit'] or cf['_freedb_mailsubmit']:
+ jack_prepare.freedb_submit()
+ sys.exit(0)
+
+-### (9) do query on start
++### do query on start
+ freedb_rename = 0
+ if cf['_query_if_needed']:
+ if not os.path.exists(cf['_freedb_form_file'] + ".bak"):
+@@ -152,7 +151,7 @@
+ if cf['_query_on_start']:
+ freedb_rename = jack_prepare.query_on_start(todo)
+
+-### (10) update freedb dbfile
++### update freedb dbfile
+ if cf['_update_freedb']:
+ if not jack_tag.track_names:
+ err, jack_tag.track_names, jack_tag.locale_names, freedb_rename, revision = jack_freedb.interpret_db_file(jack_ripstuff.all_tracks, todo, cf['_freedb_form_file'], verb = 1, dirs = 0)
+@@ -161,7 +160,12 @@
+ info("now submit your changes if you like, using the option --submit (via http POST). Don't forget to activate your changes locally with -R")
+ sys.exit(0)
+
+-### (11) undo renaming (operation mode)
++### update progress file at user's request (operation mode)
++if cf['_upd_progress']:
++ jack_prepare.update_progress(status, todo)
++ sys.exit(0)
++
++### undo renaming (operation mode)
+ if cf['_undo_rename']:
+ jack_prepare.undo_rename(status, todo)
+ sys.exit(0)
+diff -urN c/jack_prepare.py jack-3.1.1+cvs20050801/jack_prepare.py
+--- c/jack_prepare.py 2006-02-05 18:48:20.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_prepare.py 2006-02-05 19:14:17.000000000 +0000
+@@ -39,7 +39,7 @@
+
+ from jack_globals import *
+
+-tracknum = None
++global tracknum
+ datatracks = []
+
+ def find_workdir():
+@@ -210,8 +210,9 @@
+ is_submittable = 1
+ return is_submittable, track1_offset
+
+-def filter_tracks(toc_just_read):
++def filter_tracks(toc_just_read, status):
+ "filter out data tracks"
++ global datatracks
+
+ if toc_just_read and jack_helpers.helpers[cf['_ripper']].has_key("toc_cmd") and cf['_ripper'] != cf['_toc_prog']:
+ ripper_tracks = jack_functions.gettoc(cf['_ripper'])
+@@ -223,25 +224,24 @@
+ # "NUM LEN START COPY PRE CH" (not: "RIP RATE NAME")
+ if ripper_tracks[rtn][j] != jack_ripstuff.all_tracks[i][j]:
+ jack_functions.progress(i + 1, "patch", "%s %d -> %d" % (fields[j], jack_ripstuff.all_tracks[i][j], ripper_tracks[rtn][j]))
++ jack_ripstuff.all_tracks[i][j] = ripper_tracks[rtn][j]
+ debug("Track %02d %s" % (i + 1, fields[j]) + `jack_ripstuff.all_tracks[i][j]` + " != " + `ripper_tracks[rtn][j]` + " (trusting %s; to the right)" % cf['_ripper'])
+ else:
+ jack_functions.progress(i + 1, "off", "non-audio")
+ datatracks.append(i + 1)
+ info("Track %02d not found by %s. Treated as non-audio." % (i + 1, cf['_ripper']))
+-
++ if not toc_just_read:
++ datatracks += [x for x in status.keys() if status[x]["off"] and status[x]["off"] == ["non-audio"]]
+
+ def gen_todo():
+ "parse tracks from argv, generate todo"
+- global tracknum
+-
+- tracknum = {}
+- for i in jack_ripstuff.all_tracks:
+- tracknum[i[NUM]] = i
+
+ if not cf['_tracks'] and not jack_playorder.order:
+ todo = []
+ for i in jack_ripstuff.all_tracks:
+- if i[CH] == 2:
++ if i[NUM] in datatracks:
++ pass
++ elif i[CH] == 2:
+ todo.append(i)
+ else:
+ info("can't handle non audio track %i" % i[NUM])
+@@ -442,8 +442,6 @@
+ error("illegal patch %s. " % j, + "Track %02d: %s is %d" % (i, p_what, todo[jack_utils.has_track(todo, i)][fields.index(p_what)]))
+
+ if status[i]['off']:
+- if jack_utils.has_track(todo, i) >= 0:
+- del todo[jack_utils.has_track(todo, i)]
+ if jack_utils.has_track(jack_ripstuff.all_tracks_todo_sorted, i) >= 0:
+ del jack_ripstuff.all_tracks_todo_sorted[jack_utils.has_track(jack_ripstuff.all_tracks_todo_sorted, i)]
+
diff --git a/debian/patches/76_mkdirname_cleanup.patch b/debian/patches/76_mkdirname_cleanup.patch
new file mode 100644
index 0000000..daabd00
--- /dev/null
+++ b/debian/patches/76_mkdirname_cleanup.patch
@@ -0,0 +1,40 @@
+Clean-up the code in mkdirname(), but don't change any functionality.
+
+Depends on 73_err_unknown_sub.patch and 74_multi_replace_cleanup.patch
+
+--- a/jack_utils.py 2007-11-09 19:19:45.000000000 +0100
++++ b/jack_utils.py 2007-11-09 19:20:53.000000000 +0100
+@@ -168,9 +168,6 @@
+
+ def mkdirname(names, template):
+ "generate mkdir-able directory name(s)"
+- dirs = template.split(os.path.sep)
+-
+- dirs2 = []
+ if cf['_id3_year'] > 0:
+ year = `cf['_id3_year']`
+ else:
+@@ -178,16 +175,16 @@
+ replacelist = {"a": names[0][0].encode(cf['_charset'], "replace"),
+ "l": names[0][1].encode(cf['_charset'], "replace"),
+ "y": year, "g": cf['_id3_genre_txt']}
+- for i in dirs:
++ # Process substitution patterns from dir_template
++ subst = template.split(os.path.sep)
++ dirs = []
++ for i in subst:
+ x = jack_misc.multi_replace(i, replacelist, "dir_template", unusable_charmap, warn = 2)
+ exec("x = x" + cf['_char_filter'])
+- dirs2.append(x)
++ dirs.append(x)
+ if cf['_append_year'] and year:
+- dirs2[-1] = dirs2[-1] + jack_misc.multi_replace(cf['_append_year'], replacelist, "append-year", warn = 1)
+- name = ""
+- for i in dirs2:
+- name = os.path.join(name, i)
+- return dirs2, name
++ dirs[-1] += jack_misc.multi_replace(cf['_append_year'], replacelist, "append-year", warn = 1)
++ return dirs, os.path.join(*dirs)
+
+ def split_dirname(name):
+ "split path in components"
diff --git a/debian/patches/77_upd_progress_flac.patch b/debian/patches/77_upd_progress_flac.patch
new file mode 100644
index 0000000..293a33a
--- /dev/null
+++ b/debian/patches/77_upd_progress_flac.patch
@@ -0,0 +1,32 @@
+Support FLAC files in --update-progress. Debian #351459
+
+Depends on 72_upd_progress_renamed.patch and 75_fix_datatrack_rename.patch,
+and on 33_flac_mutagen.patch
+
+
+diff -urN jack-3.1.1+cvs20050801~/jack_prepare.py jack-3.1.1+cvs20050801/jack_prepare.py
+--- jack-3.1.1+cvs20050801~/jack_prepare.py 2006-04-04 23:29:16.000000000 +0200
++++ jack-3.1.1+cvs20050801/jack_prepare.py 2006-04-04 23:30:32.000000000 +0200
+@@ -38,6 +38,7 @@
+
+ from jack_globals import *
+ from jack_init import ogg
++from jack_init import flac
+
+ global tracknum
+ datatracks = []
+@@ -360,6 +361,13 @@
+ elif ext == ".ogg" and ogg:
+ x = ogg.vorbis.VorbisFile(filename + ext)
+ temp_rate = int(x.raw_total(0) * 8 / x.time_total(0) / 1000 + 0.5)
++ elif ext.upper() == ".FLAC" and flac:
++ f = flac.FLAC(filename + ext)
++ size = os.path.getsize(filename + ext)
++ if f.info and size:
++ temp_rate = int(size * 8 * f.info.sample_rate / f.info.total_samples / 1000)
++ else:
++ temp_rate = 0
+ else:
+ error("don't know how to handle %s files." % ext)
+ status[num]['enc'] = `temp_rate` + cf['_progr_sep'] + "[simulated]"
+
diff --git a/debian/patches/78_setlocale.patch b/debian/patches/78_setlocale.patch
new file mode 100644
index 0000000..25be965
--- /dev/null
+++ b/debian/patches/78_setlocale.patch
@@ -0,0 +1,16 @@
+We need to set the locale so UTF-8 characters will be printed properly, see
+the discussion in Debian #279000
+
+--- a/jack 2006-12-01 13:51:22.000000000 +0100
++++ b/jack 2007-08-29 12:50:16.000000000 +0200
+@@ -64,6 +64,9 @@
+ ###################### M A I N ###############################################
+ ##############################################################################
+
++import locale
++locale.setlocale(locale.LC_ALL, "")
++
+ # say hello...
+ print "This is", jack_version.prog_name, jack_version.prog_version, jack_version.prog_copyright, jack_version.prog_devemail
+
+
diff --git a/debian/patches/79_unicode_width.patch b/debian/patches/79_unicode_width.patch
new file mode 100644
index 0000000..164240d
--- /dev/null
+++ b/debian/patches/79_unicode_width.patch
@@ -0,0 +1,52 @@
+Try to guess the real width of a string, see comment in the patch.
+
+Without this patch, we'd get something like this:
+
+01 03:16 我的地盘 (My Territory).: 6.31x [ !] [coding @3.72x done, 133kbit
+02 05:26 七里香 (Orange Jasmine): 6.92x [ ] 2% done, ETA: 01:18, 4.03x
+03 03:56 借口 (Excuse).........: 7.51x [ ] waiting for encoder.
+04 04:46 外婆 (Grandma)........: :DAE: [ > 057812 00 ] == :^D
+ ^^^^^^^^^^^^^^^^^^^^^^^
+
+--- a/jack_ripstuff.py 2007-08-27 13:59:52.000000000 +0200
++++ b/jack_ripstuff.py 2007-08-29 12:49:41.000000000 +0200
+@@ -19,6 +19,7 @@
+ import jack_freedb
+
+ import locale
++import unicodedata
+
+ from jack_globals import *
+
+@@ -33,6 +34,21 @@
+
+ raw_space = None # free diskspace
+
++# There's currently no good way in Python to obtain the real width a string
++# will take up on the screen since it may e.g. depend on how the terminal
++# displays wide characters. This function is a first attempt to at least
++# get an approximate idea of the width of a string (assuming that wide
++# characters take up two columns on the screen). This is only to be used
++# until there's a real solution in Python.
++def width(s):
++ w = 0
++ for c in s.decode(locale.getpreferredencoding()):
++ if unicodedata.east_asian_width(c) in ("W", "F"):
++ w += 2
++ else:
++ w += 1
++ return w
++
+ def gen_printable_names(track_names, todo):
+ global printable_names
+ global max_name_len
+@@ -69,7 +85,7 @@
+ else:
+ tmp = tmp + track_names[i[NUM]][1]
+ p_tmp = tmp.encode(locale.getpreferredencoding(), "replace")
+- printable_names[i[NUM]] = p_tmp + "." * (max_name_len - len(tmp))
++ printable_names[i[NUM]] = p_tmp + "." * (max_name_len - width(p_tmp))
+ else:
+ if cf['_show_time']:
+ printable_names[i[NUM]] = ("%02i " % i[NUM]) + len_tmp + "." * (max_name_len - len(i[NAME]) - 6)
+
diff --git a/debian/patches/80_dest_exists_abs_path.patch b/debian/patches/80_dest_exists_abs_path.patch
new file mode 100644
index 0000000..4aef413
--- /dev/null
+++ b/debian/patches/80_dest_exists_abs_path.patch
@@ -0,0 +1,16 @@
+When a "destination exists already" error is displayed, show the absolute
+path rather than the one corresponding to the album name. Debian #293332.
+
+
+diff -urN jack-3.1.1~/jack_utils.py jack-3.1.1/jack_utils.py
+--- jack-3.1.1~/jack_utils.py 2005-07-28 23:18:40.722448528 +0100
++++ jack-3.1.1/jack_utils.py 2005-07-28 23:37:18.256557520 +0100
+@@ -94,7 +94,7 @@
+
+ last_of_new = new[-1]
+ if os.path.exists(last_of_new):
+- error("destination directory already exists: " + last_of_new)
++ error("destination directory already exists: " + os.path.join(*[cf['_base_dir']] + new))
+ try:
+ os.rename(cwd, last_of_new)
+ except OSError:
diff --git a/debian/patches/81_check_space.patch b/debian/patches/81_check_space.patch
new file mode 100644
index 0000000..1802059
--- /dev/null
+++ b/debian/patches/81_check_space.patch
@@ -0,0 +1,30 @@
+Fix the code which checks whether disk space has been freed outside of
+jack. Debian #200233.
+
+I'm not positive whether this fix is 100% correct but it seems to work,
+certainly better than the current broken code which never updates
+space_adjust at all. -- tbm
+
+diff -urN jack-3.1.1~/jack_main_loop.py jack-3.1.1/jack_main_loop.py
+--- jack-3.1.1~/jack_main_loop.py 2005-07-30 00:17:58.603803952 +0100
++++ jack-3.1.1/jack_main_loop.py 2005-07-30 00:18:36.513040872 +0100
+@@ -71,9 +71,8 @@
+
+ global_start = time.time()
+ while mp3s_todo or enc_queue or dae_queue or enc_running or dae_running:
+-
++ orig_space = space
+ # feed in the WAVs which have been there from the start
+-
+ if mp3s_todo and jack_functions.tracksize(mp3s_todo[0])[ENC] < space:
+ waiting_space = 0
+ enc_queue.append(mp3s_todo[0])
+@@ -358,6 +357,8 @@
+ if global_error:
+ jack_display.smile = " :-["
+
++ space_adjust += orig_space-space
++
+ if last_update + cf['_update_interval'] <= time.time():
+ last_update = time.time()
+
diff --git a/debian/patches/82_fix_append_year_doc.patch b/debian/patches/82_fix_append_year_doc.patch
new file mode 100644
index 0000000..b07f64c
--- /dev/null
+++ b/debian/patches/82_fix_append_year_doc.patch
@@ -0,0 +1,31 @@
+Fix the documentation of --append-year. The docs used to say it's a
+boolean whereas it's really a string. (A string makes sense because
+it's more flexible.)
+
+--- a/jack.man 2007-11-09 19:25:01.000000000 +0100
++++ b/jack.man 2007-11-09 19:31:04.000000000 +0100
+@@ -102,8 +102,9 @@
+ .PP
+ Jack understands the following options:
+ .TP
+-.B \-\-append-year=bool
+-if known, append the year to dir in the format " (%y)"
++.B \-\-append-year string
++append this string to the directory name (useful with %y to add the year
++an album was released)
+ .TP
+ .B \-b, \-\-bitrate int
+ target bitrate (in kbit/s, default is 160).
+--- a/jack_config.py 2007-11-09 19:31:13.000000000 +0100
++++ b/jack_config.py 2007-11-09 19:32:05.000000000 +0100
+@@ -166,8 +166,8 @@
+ },
+ 'append_year': {
+ 'type': types.StringType,
+- 'val': " (%y)",
+- 'usage': "if known, append the year to dir",
++ 'val': "",
++ 'usage': "append this string to the directory name",
+ 'long': 'AUTO',
+ },
+ 'dir_template': {
diff --git a/debian/patches/83_man_plugin.patch b/debian/patches/83_man_plugin.patch
new file mode 100644
index 0000000..9665e48
--- /dev/null
+++ b/debian/patches/83_man_plugin.patch
@@ -0,0 +1,53 @@
+Describe the plug-in mechanism in the man page. Debian #272622
+
+
+diff -urN a/jack.man jack-3.1.1+cvs20050801/jack.man
+--- a/jack.man 2006-02-05 15:54:02.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack.man 2006-02-05 15:59:14.000000000 +0000
+@@ -53,6 +53,11 @@
+ .B /etc/jackrc
+ or by saving them to
+ .BR ~/.jack3rc .
++Additional rippers, encoders and FreeDB servers can be defined by users
++through the help of a plug-in directory (as defined by the
++.BR plugin_path
++option which defaults to
++.BR ~/.jack_plugins ).
+ .PP
+ While Jack is running, these keyboard commands are available:
+ .RS
+@@ -500,6 +505,34 @@
+ jack \-O \-\-remove-files ; gnoise *wav ; jack \-g *wav ; jack
+ .RE
+ Just replace gnoise by the operation you'd like to perform.
++.SH PLUG-INS
++Additional rippers, encoders and FreeDB servers currently not known by jack
++can be defined using jack's plug-in mechanism. Plug-ins have to be put in
++the
++.BR ~/.jack_plugins
++directory (or the path defined by the
++.BR plugin_path
++option). The plug-ins are simple Python scripts which define a hash with
++the values for your ripper, encoder or FreeDB server. For rippers and
++encoders, the hash
++.BR plugin_helpers
++has to be defined while additional FreeDB servers are specified in
++.BR plugin_freedb_servers .
++Both expect another hash whose names corresponds to the entry you want to
++add (prefixed by
++.BR plugin_ )
++and have to define certain values. Two examples are provided,
++.BR jack_plugin_cddb.py
++(to define a new FreeDB server) and
++.BR jack_plugin_lame.py
++(to show how rippers and encoders can be defined). After defining
++plug-ins, you have to manually select them by specifying the ripper,
++encoder, or CDDB server. An example would be:
++.RS
++jack \-\-encoder-name plugin_lame \-\-ripper plugin_foo \-\-server plugin_cddb
++.RE
++Plug-ins can also be used to define your own rippers and encoders which
++uses different options than those used by default by jack.
+ .SH ENVIRONMENT VARIABLES
+ There are several environment variables which can be used in jack's exec
+ hooks:
diff --git a/debian/patches/84_dyear_dgenre.patch b/debian/patches/84_dyear_dgenre.patch
new file mode 100644
index 0000000..a4bf1d1
--- /dev/null
+++ b/debian/patches/84_dyear_dgenre.patch
@@ -0,0 +1,107 @@
+Add support for DYEAR and DGENRE as defined in CDDB protocol level 5.
+Debian #277932.
+
+diff -urN a/jack_freedb.py jack-3.1.1+cvs20050801/jack_freedb.py
+--- a/jack_freedb.py 2006-02-05 15:54:03.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_freedb.py 2006-02-05 15:54:32.000000000 +0000
+@@ -179,6 +179,23 @@
+ f.write(freedb_split("DTITLE", names[0][0] + " / " + names[0][1]))
+ else:
+ f.write("DTITLE=\n")
++ freedb_year, freedb_id3genre = -1, -1
++ if cf['_id3_genre'] >= 0 and cf['_id3_genre'] < len(id3genres) or cf['_id3_genre'] == 255:
++ freedb_id3genre = cf['_id3_genre']
++ elif names and len(names[0]) == 4:
++ freedb_id3genre = names[0][3]
++ if cf['_id3_year'] >= 0:
++ freedb_year = cf['_id3_year']
++ elif names and len(names[0]) == 4:
++ freedb_year = names[0][2]
++ if freedb_year >= 0:
++ f.write("DYEAR=%d\n" % freedb_year)
++ else:
++ f.write("DYEAR=\n")
++ if freedb_id3genre >= 0:
++ f.write("DGENRE=%s\n" % id3genres[freedb_id3genre])
++ else:
++ f.write("DGENRE=\n")
+ for i in tracks:
+ if names:
+ if names[i[NUM]][0]: # various
+@@ -193,15 +210,6 @@
+ f.write(freedb_split("TTITLE" + `i[NUM]-1`, names[i[NUM]][1]))
+ else:
+ f.write("TTITLE" + `i[NUM]-1` + "=\n")
+- freedb_year, freedb_id3genre = -1, -1
+- if cf['_id3_genre'] >= 0 and cf['_id3_genre'] < len(id3genres) or cf['_id3_genre'] == 255:
+- freedb_id3genre = cf['_id3_genre']
+- elif names and len(names[0]) == 4:
+- freedb_id3genre = names[0][3]
+- if cf['_id3_year'] >= 0:
+- freedb_year = cf['_id3_year']
+- elif names and len(names[0]) == 4:
+- freedb_year = names[0][2]
+ if freedb_year >= 0 or freedb_id3genre >= 0:
+ f.write("EXTD=\\nYEAR: %4s ID3G: %3s\n" % (freedb_year, freedb_id3genre))
+ else:
+@@ -338,7 +346,7 @@
+ line = string.replace(line, "\r", "") # I consider "\r"s as bugs in db info
+ if jack_functions.starts_with(line, "# Revision:"):
+ revision = int(line[11:])
+- for i in ["DISCID", "DTITLE", "TTITLE", "EXTD", "EXTT", "PLAYORDER"]:
++ for i in ["DISCID", "DTITLE", "DYEAR", "DGENRE", "TTITLE", "EXTD", "EXTT", "PLAYORDER"]:
+ if jack_functions.starts_with(line, i):
+ buf = line
+ if string.find(buf, "=") != -1:
+@@ -418,7 +426,29 @@
+ dtitle = "(unknown artist)/" + dtitle
+
+ names = [string.split(dtitle,"/",1)]
+- if freedb.has_key('EXTD'):
++ year = -1
++ if freedb.has_key('DYEAR'):
++ try:
++ year = int(freedb['DYEAR'])
++ except ValueError:
++ warning("DYEAR has to be an integer but it's the string '%s'" % freedb['DYEAR'])
++ else:
++ if year == 0:
++ warning("DYEAR should not be 0 but empty")
++ genre = -1
++ if freedb.has_key('DGENRE'):
++ try:
++ genre = int(freedb['DGENRE'])
++ except ValueError:
++ if freedb['DGENRE'].upper() in [x.upper() for x in id3genres]:
++ genre = [x.upper() for x in id3genres].index(freedb['DGENRE'].upper())
++ else:
++ warning("DGENRE should be a string, not an integer.")
++ if genre != -1:
++ names[0].extend([year, genre])
++ elif year != -1:
++ names[0].extend([year])
++ if freedb.has_key('EXTD') and not(freedb.has_key('DYEAR') or freedb.has_key('DGENRE')):
+ extra_tag_pos = string.find(freedb['EXTD'], "\\nYEAR:")
+ if extra_tag_pos >= 0:
+ try:
+diff -urN a/jack_tag.py jack-3.1.1+cvs20050801/jack_tag.py
+--- a/jack_tag.py 2006-02-05 15:54:03.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_tag.py 2006-02-05 15:54:25.000000000 +0000
+@@ -65,12 +65,11 @@
+
+ if cf['_set_id3tag'] or freedb_rename:
+ jack_m3u.init()
+- if len(track_names[0]) == 4:
+- # use freedb year and genre data if available
+- if cf['_id3_genre'] == -1:
+- cf['_id3_genre'] = track_names[0][3]
+- if cf['_id3_year'] == -1:
+- cf['_id3_year'] = track_names[0][2]
++ # use freedb year and genre data if available
++ if cf['_id3_year'] == -1 and len(track_names[0]) >= 3:
++ cf['_id3_year'] = track_names[0][2]
++ if cf['_id3_genre'] == -1 and len(track_names[0]) == 4:
++ cf['_id3_genre'] = track_names[0][3]
+
+ print "Tagging",
+ for i in jack_ripstuff.all_tracks_todo_sorted:
diff --git a/debian/patches/85_dir_template_yg.patch b/debian/patches/85_dir_template_yg.patch
new file mode 100644
index 0000000..5e17fb3
--- /dev/null
+++ b/debian/patches/85_dir_template_yg.patch
@@ -0,0 +1,54 @@
+Make %y and %g actually work dir_template (when the user doesn't explicitly
+specify it with -G and -Y). First we need to set it when doing the FreeDB
+lookup, and secondly we need to use the right variable for the replacement.
+_id3_genre_txt is not set anywhere at all. Debian #351574
+
+Depends on 76_mkdirname_cleanup.patch and 84_dyear_dgenre.patch
+
+--- orig/jack_freedb.py 2006-03-02 18:37:52.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_freedb.py 2006-03-02 18:37:56.000000000 +0000
+@@ -525,6 +525,10 @@
+ if freedb.has_key('DYEAR'):
+ try:
+ year = int(freedb['DYEAR'])
++ if cf['_id3_year'] <= 0:
++ cf['_id3_year'] = year
++ elif cf['_id3_year'] != year:
++ warning("Specified and FreeDB year differ (%d vs %d)" % (cf['_id3_year'], year))
+ except ValueError:
+ warning("DYEAR has to be an integer but it's the string '%s'" % freedb['DYEAR'])
+ else:
+@@ -537,6 +541,11 @@
+ except ValueError:
+ if freedb['DGENRE'].upper() in [x.upper() for x in id3genres]:
+ genre = [x.upper() for x in id3genres].index(freedb['DGENRE'].upper())
++ if cf['_id3_genre'] <= 0:
++ cf['_id3_genre'] = genre
++ elif cf['_id3_genre'] != genre:
++ warning("Specified and FreeDB genre differ (%s vs %s)" %
++ (id3genres[cf['_id3_genre']], id3genres[genre]))
+ else:
+ warning("DGENRE should be a string, not an integer.")
+ if freedb.has_key('EXTD') and not freedb.has_key('DYEAR'):
+diff -urN orig/jack_utils.py jack-3.1.1+cvs20050801/jack_utils.py
+--- orig/jack_utils.py 2006-03-02 18:37:52.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_utils.py 2006-03-02 18:38:15.000000000 +0000
+@@ -168,13 +168,14 @@
+
+ def mkdirname(names, template):
+ "generate mkdir-able directory name(s)"
++ year = genretxt = None
+ if cf['_id3_year'] > 0:
+ year = `cf['_id3_year']`
+- else:
+- year = None
++ if cf['_id3_genre'] != -1:
++ genretxt = id3genres[cf['_id3_genre']]
+ replacelist = {"a": names[0][0].encode(cf['_charset'], "replace"),
+ "l": names[0][1].encode(cf['_charset'], "replace"),
+- "y": year, "g": cf['_id3_genre_txt']}
++ "y": year, "g": genretxt}
+ # Process substitution patterns from dir_template
+ subst = template.split(os.path.sep)
+ dirs = []
+
diff --git a/debian/patches/86_mention_year_dir_template.patch b/debian/patches/86_mention_year_dir_template.patch
new file mode 100644
index 0000000..ec4984d
--- /dev/null
+++ b/debian/patches/86_mention_year_dir_template.patch
@@ -0,0 +1,14 @@
+%y is a valid option for dir_template too.
+
+--- a/jack_config.py 2007-11-09 19:12:11.000000000 +0100
++++ b/jack_config.py 2007-11-09 19:12:59.000000000 +0100
+@@ -175,7 +175,8 @@
+ 'doc': """specify how the resulting files are named:
+ %a: artist
+ %l: album title
+- %g: album genre - individual track genres are unsupported""",
++ %g: album genre - individual track genres are unsupported
++ %y: album release year - individual track years are unsupported""",
+ 'long': 'AUTO',
+ },
+ 'char_filter': {
diff --git a/debian/patches/87_use_existing_cddb_category.patch b/debian/patches/87_use_existing_cddb_category.patch
new file mode 100644
index 0000000..d9cf6e2
--- /dev/null
+++ b/debian/patches/87_use_existing_cddb_category.patch
@@ -0,0 +1,121 @@
+When submitting updated CDDB entries, use the existing CDDB category of the
+CD instead of prompting the user for it. Debian #335299. (Note that there
+might be no CDDB category yet when -Q and --cont-failed-query is used;
+Debian #453724).
+
+
+Won't cleanly apply without 25_ignore_empty_freedb_info.patch but doesn't
+depend on it.
+
+
+diff -urN a/jack_freedb.py jack-3.1.1+cvs20050801/jack_freedb.py
+--- a/jack_freedb.py 2006-02-05 15:37:18.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_freedb.py 2006-02-05 15:37:12.000000000 +0000
+@@ -651,34 +651,35 @@
+
+ return cat[x]
+
+-def do_freedb_submit(file, cd_id):
++def do_freedb_submit(file, cd_id, cat = None):
+ import httplib
+
+- hello = "hello=" + cf['_username'] + " " + cf['_hostname'] + " " + prog_name + " " + prog_version
+- print "Info: querying categories..."
+- url = "http://" + freedb_servers[cf['_freedb_server']]['host'] + "/~cddb/cddb.cgi?" + urllib.quote_plus("cmd=cddb lscat" + "&" + hello + "&proto=6", "=&")
+- f = urllib2.urlopen(url)
+- buf = f.readline()
+- if buf[0:3] == "500":
+- print "Info: LSCAT failed, using builtin categories..."
+- cat = choose_cat()
+-
+- elif buf[0:3] == "210":
+- cat = ["null", ]
+- while 1:
+- buf = f.readline()
+- if not buf:
+- break
+- buf = string.rstrip(buf)
+- if buf != ".":
+- cat.append(buf)
+- f.close()
+- cat = choose_cat(cat)
++ if not cat:
++ hello = "hello=" + cf['_username'] + " " + cf['_hostname'] + " " + prog_name + " " + prog_version
++ print "Info: querying categories..."
++ url = "http://" + freedb_servers[cf['_freedb_server']]['host'] + "/~cddb/cddb.cgi?" + urllib.quote_plus("cmd=cddb lscat" + "&" + hello + "&proto=6", "=&")
++ f = urllib2.urlopen(url)
++ buf = f.readline()
++ if buf[0:3] == "500":
++ print "Info: LSCAT failed, using builtin categories..."
++ cat = choose_cat()
++
++ elif buf[0:3] == "210":
++ cat = ["null", ]
++ while 1:
++ buf = f.readline()
++ if not buf:
++ break
++ buf = string.rstrip(buf)
++ if buf != ".":
++ cat.append(buf)
++ f.close()
++ cat = choose_cat(cat)
+
+- else:
+- error("LSCAT failed: " + string.rstrip(buf) + f.read())
++ else:
++ error("LSCAT failed: " + string.rstrip(buf) + f.read())
+
+- print "OK, using `" + cat + "'."
++ print "OK, using category `" + cat + "'."
+ email = freedb_servers[cf['_freedb_server']]['my_mail']
+ print "Your e-mail address is needed to send error messages to you."
+ x = raw_input("enter your e-mail-address [" + email + "]: ")
+@@ -757,11 +758,12 @@
+ print "consider submitting via mail (" + progname + " -m). full error:\n"
+ print err, msg
+
+-def do_freedb_mailsubmit(file, cd_id):
++def do_freedb_mailsubmit(file, cd_id, cat = None):
+ warning("Support for freedb submission via e-mail may be dropped in future versions. Please begin to use HTTP to submit your entries (--submit)")
+ sendmail = '/usr/lib/sendmail -t'
+ #sendmail = 'cat > /tmp/jack.test.mailsubmit'
+- cat = choose_cat()
++ if not cat:
++ cat = choose_cat()
+ print "OK, using `" + cat + "'."
+ if string.find(freedb_servers[cf['_freedb_server']]['my_mail'], "@") >= 1 and len(freedb_servers[cf['_freedb_server']]['my_mail']) > 3:
+ return os.system("( echo 'To: " + freedb_servers[cf['_freedb_server']]['mail'] + "'; echo From: '" + freedb_servers[cf['_freedb_server']]['my_mail'] + "'; echo 'Subject: cddb " + cat + " " + cd_id + "' ; cat '" + file + "' ) | " + sendmail)
+diff -urN a/jack_prepare.py jack-3.1.1+cvs20050801/jack_prepare.py
+--- a/jack_prepare.py 2006-02-05 15:37:18.000000000 +0000
++++ jack-3.1.1+cvs20050801/jack_prepare.py 2006-02-05 15:37:12.000000000 +0000
+@@ -461,7 +461,7 @@
+
+ return status
+
+-def freedb_submit():
++def freedb_submit(cat = None):
+ "submit freedb data on user's request"
+ if not is_submittable:
+ error("can't submit in current state, please fix jack.freedb")
+@@ -471,9 +471,9 @@
+ error("invalid freedb file")
+ else:
+ if cf['_freedb_mailsubmit']:
+- jack_freedb.do_freedb_mailsubmit(cf['_freedb_form_file'], cd_id)
++ jack_freedb.do_freedb_mailsubmit(cf['_freedb_form_file'], cd_id, cat)
+ else:
+- jack_freedb.do_freedb_submit(cf['_freedb_form_file'], cd_id)
++ jack_freedb.do_freedb_submit(cf['_freedb_form_file'], cd_id, cat)
+
+ ### (9) do query on start
+
+@@ -516,7 +516,7 @@
+ x = raw_input("Would you like to submit these changes to the FreeDB server? (y/N) ")
+ if string.upper(x[0]) == "Y":
+ jack_freedb.update_revision(file)
+- freedb_submit()
++ freedb_submit(jack_progress.status_all.get('freedb_cat', None))
+
+ if cf['_query_on_start']:
+ err, jack_tag.track_names, jack_tag.locale_names, freedb_rename, revision = jack_freedb.interpret_db_file(jack_ripstuff.all_tracks, todo, cf['_freedb_form_file'], verb = cf['_query_on_start'], dirs = 1)
diff --git a/debian/patches/88_fix_argv_loop.patch b/debian/patches/88_fix_argv_loop.patch
new file mode 100644
index 0000000..e37b595
--- /dev/null
+++ b/debian/patches/88_fix_argv_loop.patch
@@ -0,0 +1,27 @@
+Fix an endless loop in the parsing of certain command line arguments.
+Debian #336911.
+
+--- a/jack_argv.py~ 2005-11-01 19:22:23.000000000 +0000
++++ b/jack_argv.py 2005-11-01 19:25:27.000000000 +0000
+@@ -61,10 +61,10 @@
+ else:
+ print "These are the most commom options. For a complete list, run jack --longhelp"
+
+-def get_next(argv, i, extra_arg = None):
++def get_next(argv, i, extra_arg = None, allow_equal = 1):
+ if extra_arg != None:
+ return i, extra_arg
+- elif argv[i].find("=") > 0:
++ elif allow_equal and argv[i].find("=") > 0:
+ return i, argv[i].split("=", 1)[1]
+ else:
+ i = i + 1
+@@ -118,7 +118,7 @@
+ l = []
+ if origin == "argv":
+ while 1:
+- i, data = get_next(argv, i, alt_arg)
++ i, data = get_next(argv, i, alt_arg, 0)
+ if data != None:
+ if data == ";":
+ break
diff --git a/debian/patches/89_saner_argv_lists.patch b/debian/patches/89_saner_argv_lists.patch
new file mode 100644
index 0000000..f9d4edf
--- /dev/null
+++ b/debian/patches/89_saner_argv_lists.patch
@@ -0,0 +1,35 @@
+Make parsing of lists given on the command line more intuitive. Debian
+#336343.
+
+
+Depends on 88_fix_argv_loop.patch
+
+
+
+--- a/jack_argv.py~ 2005-11-01 19:30:34.000000000 +0000
++++ b/jack_argv.py 2005-11-01 19:41:11.000000000 +0000
+@@ -117,11 +117,23 @@
+ if ty == types.ListType:
+ l = []
+ if origin == "argv":
++ valid_short_opts = [cf[key]['short'] for key in cf.keys() if cf[key].has_key('short')]
++ valid_long_opts = [cf[key]['long'] for key in cf.keys() if cf[key].has_key('long')]
+ while 1:
+ i, data = get_next(argv, i, alt_arg, 0)
+ if data != None:
+ if data == ";":
+ break
++ # The end of a list has to be signaled with a semicolon but
++ # many users forget this; therefore, check whether the next list
++ # entry is a valid option, and if so, assume the end of the list
++ # has been reached.
++ if data.startswith("--") and data[2:].split('=', 1)[0] in valid_long_opts:
++ i -= 1
++ break
++ if data.startswith("-") and len(data) == 2 and data[1] in valid_short_opts:
++ i -= 1
++ break
+ l.append(data)
+ if alt_arg: # only one option in --opt=val form
+ break
+
diff --git a/debian/patches/90_fix_df.patch b/debian/patches/90_fix_df.patch
new file mode 100644
index 0000000..ebe0b29
--- /dev/null
+++ b/debian/patches/90_fix_df.patch
@@ -0,0 +1,24 @@
+Fix the alternative path of jack_functions.df():
+ - close p after reading from it, not before...
+ - get rid of 'keep_free' which is no defined. It's really cf['_keep_free']
+ but it should not be there anyway since the code which calls
+ jack_functions.df() will deduct it.
+ - also close p when 'Available' is not found (unlikely, but still...)
+
+Debian #324946.
+
+--- a/jack_functions.py~ 2005-11-01 21:06:30.000000000 +0000
++++ b/jack_functions.py 2005-11-01 21:14:33.000000000 +0000
+@@ -53,9 +53,10 @@
+ s = string.split(string.rstrip(p.readline()))
+ for i in range(len(s)):
+ if s[i] == "Available":
+- p.close()
+ s = string.split(string.rstrip(p.readline()))
+- return int(s[i]) * long(blocksize) - long(keep_free)
++ p.close()
++ return int(s[i]) * long(blocksize)
++ p.close()
+
+ def get_sysload_linux_proc():
+ "extract sysload from /proc/loadavg, linux only (?)"
diff --git a/debian/patches/91_fix_cdrdao_image.patch b/debian/patches/91_fix_cdrdao_image.patch
new file mode 100644
index 0000000..f5d8755
--- /dev/null
+++ b/debian/patches/91_fix_cdrdao_image.patch
@@ -0,0 +1,34 @@
+Fix support for cdrdao image files. Debian #338697.
+
+
+diff -urN jack-3.1.1~/jack_main_loop.py jack-3.1.1/jack_main_loop.py
+--- jack-3.1.1~/jack_main_loop.py 2005-11-12 16:50:35.000000000 +0000
++++ jack-3.1.1/jack_main_loop.py 2005-11-12 17:52:31.000000000 +0000
+@@ -392,10 +392,11 @@
+ #jack_term.tmod.dae_stat_upd(i['track'][NUM], None, i['percent'])
+
+ elif i['type'] == "image_reader":
+- line = string.strip(jack_status.get_2_line(i['buf']))
+- jack_status.dae_stat_upd(i['track'][NUM], line)
+- if line.startswith("Error"):
+- global_error = global_error + 1
++ line = string.strip(jack_status.get_2_line(i['buf'], default=""))
++ if line:
++ jack_status.dae_stat_upd(i['track'][NUM], line)
++ if line.startswith("Error"):
++ global_error = global_error + 1
+
+ else:
+ error("unknown subprocess type \"" + i['type'] + "\".")
+diff -urN jack-3.1.1~/jack_workers.py jack-3.1.1/jack_workers.py
+--- jack-3.1.1~/jack_workers.py 2005-11-12 16:50:35.000000000 +0000
++++ jack-3.1.1/jack_workers.py 2005-11-12 16:50:49.000000000 +0000
+@@ -315,7 +315,7 @@
+ #
+ ## set up output wav file:
+ #
+- wav = wave.open(track[NAME].decode(cf['_charset'], "replace") + ".wav", 'w')
++ wav = wave.open(track[NAME] + ".wav", 'w')
+ wav.setnchannels(2)
+ wav.setsampwidth(2)
+ wav.setframerate(44100)
diff --git a/debian/patches/92_fix_python2.6_warning.patch b/debian/patches/92_fix_python2.6_warning.patch
new file mode 100644
index 0000000..08ce231
--- /dev/null
+++ b/debian/patches/92_fix_python2.6_warning.patch
@@ -0,0 +1,21 @@
+Fix the following warning:
+
+/var/lib/python-support/python2.5/jack_functions.py:243: Warning: 'with' will become a reserved keyword in Python 2.6
+/var/lib/python-support/python2.5/jack_functions.py:245: Warning: 'with' will become a reserved keyword in Python 2.6
+/var/lib/python-support/python2.5/jack_functions.py:245: Warning: 'with' will become a reserved keyword in Python 2.6
+
+--- a/jack_functions.py 2007-10-20 12:24:55.000000000 +0200
++++ b/jack_functions.py 2007-10-20 12:25:24.000000000 +0200
+@@ -240,9 +240,9 @@
+ ff = blocks % CDDA_BLOCKS_PER_SECOND
+ return mm, ss, ff, blocks
+
+-def starts_with(str, with):
+- "checks whether str starts with with"
+- return str[0:len(with)] == with
++def starts_with(str, x):
++ "checks whether str starts with a given string x"
++ return str[0:len(x)] == x
+
+ ## #XXX the following will be used if all references to it have been updated.
+ ## meanwhile the wrapper below is used.
diff --git a/debian/patches/93_extd_parsing.patch b/debian/patches/93_extd_parsing.patch
new file mode 100644
index 0000000..7eec713
--- /dev/null
+++ b/debian/patches/93_extd_parsing.patch
@@ -0,0 +1,44 @@
+Make the parsing of year and genre in EXTD less restrictive. Now it will
+recognize the year even if there is no genre and if there is space instead
+of newline between year and EXTD. Debian #341891.
+
+Depends on 84_dyear_dgenre.patch
+
+diff -urN jack-3.1.1~/jack_freedb.py jack-3.1.1/jack_freedb.py
+--- jack-3.1.1~/jack_freedb.py 2005-12-03 21:50:24.000000000 +0000
++++ jack-3.1.1/jack_freedb.py 2005-12-03 21:57:59.000000000 +0000
+@@ -449,22 +449,22 @@
+ genre = [x.upper() for x in id3genres].index(freedb['DGENRE'].upper())
+ else:
+ warning("DGENRE should be a string, not an integer.")
++ if freedb.has_key('EXTD') and not freedb.has_key('DYEAR'):
++ extra_tag_pos = string.find(freedb['EXTD'], "YEAR:")
++ if extra_tag_pos >= 0:
++ arg = freedb['EXTD'][extra_tag_pos + 5:].lstrip().split()[0]
++ if arg.isdigit():
++ year = int(arg)
++ if freedb.has_key('EXTD') and not freedb.has_key('DGENRE'):
++ extra_tag_pos = string.find(freedb['EXTD'], "ID3G:")
++ if extra_tag_pos >= 0:
++ arg = freedb['EXTD'][extra_tag_pos + 5:].lstrip().split()[0]
++ if arg.isdigit():
++ genre = int(arg)
+ if genre != -1:
+ names[0].extend([year, genre])
+ elif year != -1:
+ names[0].extend([year])
+- if freedb.has_key('EXTD') and not(freedb.has_key('DYEAR') or freedb.has_key('DGENRE')):
+- extra_tag_pos = string.find(freedb['EXTD'], "\\nYEAR:")
+- if extra_tag_pos >= 0:
+- try:
+- extd_info = freedb['EXTD'][extra_tag_pos + 7:]
+- extd_year, extd_id3g = string.split(extd_info, "ID3G:", 1)
+- extd_year, extd_id3g = int(extd_year), int(extd_id3g)
+- except:
+- print "can't handle '%s'." % freedb['EXTD']
+- else:
+- names = [string.split(dtitle, "/", 1)]
+- names[0].extend([extd_year, extd_id3g])
+ if names[0][0] == "(unknown artist)":
+ if verb:
+ warning("the disc's title must be set to \"artist / title\" (\"DTITLE\").")
diff --git a/debian/patches/94_addstr_error.patch b/debian/patches/94_addstr_error.patch
new file mode 100644
index 0000000..a19be71
--- /dev/null
+++ b/debian/patches/94_addstr_error.patch
@@ -0,0 +1,40 @@
+Debian bug #401127, related to #387648 (99_addstr_error.patch). Probably a
+workaround, not a real fix.
+
+
+I see tracebacks like this a lot when the tags have "funny" characters:
+
+Traceback (most recent call last):
+ File "/usr/bin/jack", line 235, in ?
+ global_error = jack_main_loop.main_loop(mp3s_todo, wavs_todo, space, dae_queue, enc_queue, track1_offset)
+ File "/var/lib/python-support/python2.3/jack_main_loop.py", line 374, in main_loop
+ jack_status.dae_stat_upd(i['track'][NUM], ":DAE: " + new_status)
+ File "/var/lib/python-support/python2.3/jack_status.py", line 51, in dae_stat_upd
+ jack_term.tmod.dae_stat_upd(num, string)
+ File "/var/lib/python-support/python2.3/jack_t_curses.py", line 262, in dae_stat_upd
+ status_pad.addstr(map_track_num[num], 0, (jack_ripstuff.printable_names[num] + ": " + jack_status.dae_status[num] + " " + jack_status.enc_status[num]))
+curses.error: addstr() returned ERR
+ *warning* abnormal exit
+
+
+It's just a display error; it really shouldn't abort jack. The following
+patch makes it not abort:
+
+
+diff -dU3 /tmp/old.py /var/lib/python-support/python2.3/jack_main_loop.py
+--- a/old.py 2006-11-30 19:08:06.000000000 -0500
++++ b/jack_main_loop.py 2006-11-30 19:00:31.000000000 -0500
+@@ -371,7 +371,10 @@
+ else:
+ exec(jack_helpers.helpers[i['prog']]['status_fkt']) in globals(), locals()
+ if new_status:
+- jack_status.dae_stat_upd(i['track'][NUM], ":DAE: " + new_status)
++ try:
++ jack_status.dae_stat_upd(i['track'][NUM], ":DAE: " + new_status)
++ except:
++ debug("error in dae_stat_upd")
+
+ elif i['type'] == "encoder":
+ if len(i['buf']) == jack_helpers.helpers[i['prog']]['status_blocksize']:
+
+
diff --git a/debian/patches/95_fix_empty_input.patch b/debian/patches/95_fix_empty_input.patch
new file mode 100644
index 0000000..fe6470b
--- /dev/null
+++ b/debian/patches/95_fix_empty_input.patch
@@ -0,0 +1,42 @@
+Don't fail when enter is pressed at an input prompt; closes: #345614.
+
+Depends on 87_use_existing_cddb_category.patch
+
+
+diff -urN jack-3.1.1~/jack_prepare.py jack-3.1.1/jack_prepare.py
+--- jack-3.1.1~/jack_prepare.py 2006-01-02 10:15:43.000000000 +0100
++++ jack-3.1.1/jack_prepare.py 2006-01-02 10:18:24.000000000 +0100
+@@ -487,8 +487,8 @@
+ if jack_freedb.freedb_query(jack_freedb.freedb_id(jack_ripstuff.all_tracks), jack_ripstuff.all_tracks, cf['_freedb_form_file']):
+ if cf['_cont_failed_query']:
+
+- x = raw_input("\nfreedb search failed, continue? ") + "x"
+- if string.upper(x[0]) != "Y":
++ x = raw_input("\nfreedb search failed, continue? (y/N) ") + "x"
++ if not x or x[0].upper() != "Y":
+ sys.exit(0)
+ cf['_query_on_start'] = 0
+ else:
+@@ -519,7 +519,7 @@
+ print
+ print pdiff
+ x = raw_input("Would you like to submit these changes to the FreeDB server? (y/N) ")
+- if string.upper(x[0]) == "Y":
++ if x and x[0].upper() == "Y":
+ jack_freedb.update_revision(file)
+ freedb_submit(jack_progress.status_all['freedb_cat'])
+
+@@ -753,11 +753,11 @@
+ print "/\\" * 40
+ for i in remove_q:
+ print i
+- x = raw_input("These files will be deleted, continue? ") + "x"
++ x = raw_input("These files will be deleted, continue? (y/N) ") + "x"
+ if cf['_force']:
+ info("(forced)")
+ else:
+- if string.upper(x[0]) != "Y":
++ if not x or x[0].upper() != "Y":
+ sys.exit(0)
+
+ for i in remove_q:
diff --git a/debian/patches/96_fix_cdda2wav_parsing.patch b/debian/patches/96_fix_cdda2wav_parsing.patch
new file mode 100644
index 0000000..8b40b07
--- /dev/null
+++ b/debian/patches/96_fix_cdda2wav_parsing.patch
@@ -0,0 +1,33 @@
+Make cdda2wav parsing more robust, in particular when errors occur.
+
+
+diff -urN jack-3.1.1~/jack_helpers.py jack-3.1.1/jack_helpers.py
+--- jack-3.1.1~/jack_helpers.py 2006-01-23 23:40:49.000000000 +0000
++++ jack-3.1.1/jack_helpers.py 2006-01-24 00:44:57.000000000 +0000
+@@ -321,10 +321,23 @@
+ 'status_fkt': r"""
+ tmp = string.split(i['buf'], "\r")
+ if len(tmp) >= 2:
+- if string.find(tmp[-2], '%') != -1:
+- new_status = "ripping: " + string.strip(tmp[-2])
+- else:
++ tmp = tmp[-2].lstrip()
++ pct = tmp.find("%")
++ if pct == -1:
+ new_status = "waiting..."
++ else:
++ # A normal line when it's ripping looks like this:
++ # 7%
++ # However, when an error occurs, it'll look something like this:
++ # 0%cdda2wav: Operation not permitted. Cannot send SCSI cmd via ioctl
++ info = tmp[:pct+1]
++ error = info + "cdda2wav:"
++ if tmp == info:
++ new_status = "ripping: " + info
++ elif tmp.startswith(error):
++ new_status = "Error: " + tmp[len(error):].lstrip()
++ else:
++ new_status = "Cannot parse status"
+ else:
+ new_status = "Cannot parse status"
+ """,
diff --git a/debian/patches/97_man_mp3vsogg.patch b/debian/patches/97_man_mp3vsogg.patch
new file mode 100644
index 0000000..5861328
--- /dev/null
+++ b/debian/patches/97_man_mp3vsogg.patch
@@ -0,0 +1,90 @@
+By default, OGGs are generated now rather than MP3s so update the examples
+in the man page. Thanks, David Whitmarsh. Debian #348547.
+
+--- jack~/jack.man 2006-01-27 15:12:00.000000000 +0000
++++ jack/jack.man 2006-01-27 15:19:09.000000000 +0000
+@@ -23,8 +23,8 @@
+ .SH DESCRIPTION
+ .B Jack
+ transforms your audio-CDs to FLAC, MP3 or Ogg Vorbis files. It uses several
+-helper programs in order to achieve things like ripping, encoding and
+-ID3-tagging. Ripping is either done via
++helper programs in order to achieve functions such as ripping, encoding and,
++tagging files with meta information. Ripping is either done via
+ .B cdparanoia
+ (in which case the ripping status is displayed by Jack as well) or
+ .B cdda2wav.
+@@ -33,11 +33,10 @@
+ and
+ .B xing.
+ Any time during operation (and even when everything is finished and
+-the original CD lost) you can let Jack look up the track names at
++the original CD lost) you can let Jack look up the track names at
+ .B freedb.org
+-and rename the tracks accordingly. ID3-tagging of MP3s (or insertion
+-of equivalent comment fields in Ogg Vorbis files) is performed
+-as well.
++and rename the tracks accordingly. Tagging of audio files with meta
++information about artist, track title, etc. is performed as well.
+ .PP
+ If no freedb-lookup has been performed, Jack drops all files in a
+ directory
+@@ -48,7 +47,7 @@
+ This directory is renamed by Jack when the appropriate information is known.
+ .PP
+ Most options like ripper, encoder, preferred FreeDB-Server, directory
+-and MP3-filename format, etc. can be user defined by changing the
++and sound file format, etc. can be user defined by changing the
+ defaults in
+ .B /etc/jackrc
+ or by saving them to
+@@ -196,15 +195,15 @@
+ the TOC is read from the CD itself.
+ .TP
+ .B \-g, \-\-guess-toc list
+-make up a TOC from the MP3 file given in mp3_files. Format is
+-.B track_01.mp3 ... track_nn.mp3 ;
++make up a TOC from the list of sound file given. The format is
++.B track_01.ogg ... track_nn.ogg ;
+ Note that the trailing "
+ .B ;
+ " is only necessary if you want to
+ append more options to your command line.
+-You can use it to do a FreeDB query based on
+-MP3s alone - no need for the CD. Very useful if you have no idea
+-which CD the MP3s are from. The MP3s must be given in the same
++You can use it to do a FreeDB query based on your sound files
++alone - no need for the CD. Very useful if you have no idea
++which CD the songs are from. The songs must be given in the same
+ order as they were on their CD. The generated TOC file is
+ similar, but not identical to the TOC of the CD - do not submit
+ these!
+@@ -213,7 +212,8 @@
+ set ID3 genre. Use 'help' to get a list of all known genres. (You can also specify the ID3v1 genre as an int)
+ .TP
+ .B \-Y, \-\-id3-year int
+-set ID3 year.
++set the year of the album (the term ID3 comes from MP3 but this option also
++works with other audio formats, such as OGG Vorbis and FLAC)
+ .TP
+ .B \-h, \-\-help
+ Show summary of options.
+@@ -298,7 +298,7 @@
+ is used,
+ then the file is queried from your FreeDB server). If you have
+ changed its contents (e.g. because the CD was unknown to FreeDB)
+-and want to rename and tag your MP3s accordingly, use this option.
++and want to rename and tag your audio files accordingly, use this option.
+ Give all other needed options too, like
+ .B \-t
+ ,
+@@ -379,7 +379,7 @@
+ undo file renaming and exit. If you don't like how Jack renamed
+ your files, use this option to restore the previous state.
+ Several levels of undo are possible. Note
+-that ID3 tags are not restored.
++that meta information tags are not restored.
+ .TP
+ .B \-\-unusable-chars list
+ characters which can't be used in filenames (default "/").
+
diff --git a/debian/patches/98_man_default_encoders.patch b/debian/patches/98_man_default_encoders.patch
new file mode 100644
index 0000000..5e0384d
--- /dev/null
+++ b/debian/patches/98_man_default_encoders.patch
@@ -0,0 +1,13 @@
+Mention the default of the --encoders option in the man page.
+
+--- jack/jack.man~ 2006-01-27 15:20:25.000000000 +0000
++++ jack/jack.man 2006-01-27 15:21:19.000000000 +0000
+@@ -160,7 +160,7 @@
+ .B \-e, \-\-encoders int
+ encode how many files in parallel. If you have a SMP machine or
+ simply want to stress your system, you can have Jack encode
+-several files at once.
++several files at once (default 1).
+ .TP
+ .B \-x, \-\-exec
+ run predefined command when finished.
diff --git a/debian/patches/99_addstr_error.patch b/debian/patches/99_addstr_error.patch
new file mode 100644
index 0000000..ff5b975
--- /dev/null
+++ b/debian/patches/99_addstr_error.patch
@@ -0,0 +1,43 @@
+This is a _workaround_ for Debian #387648 - a testcase can be found in that
+bug.
+
+
+diff -urN jack-3.1.1+cvs20050801~/jack_t_curses.py jack-3.1.1+cvs20050801/jack_t_curses.py
+--- jack-3.1.1+cvs20050801~/jack_t_curses.py 2006-10-24 21:10:12.000000000 +0100
++++ jack-3.1.1+cvs20050801/jack_t_curses.py 2006-10-24 21:11:16.000000000 +0100
+@@ -33,11 +33,11 @@
+ enabled = None
+
+ try:
+- from jack_curses import endwin, resizeterm, A_REVERSE, newwin, newpad, initscr, noecho, cbreak, echo, nocbreak
++ from jack_curses import endwin, resizeterm, A_REVERSE, newwin, newpad, initscr, noecho, cbreak, echo, nocbreak, error
+ except ImportError:
+ warning("jack_curses module not found, trying normal curses...")
+ try:
+- from curses import endwin, A_REVERSE, newwin, newpad, initscr, noecho, cbreak, echo, nocbreak
++ from curses import endwin, A_REVERSE, newwin, newpad, initscr, noecho, cbreak, echo, nocbreak, error
+ def resizeterm(y, x):
+ pass
+ except ImportError:
+@@ -255,11 +255,17 @@
+ front = jack_ripstuff.printable_names[num] + ": " + jack_status.dae_status[num][:6]
+ middle = jack_status.dae_status[num][6:split_point]
+ end = jack_status.dae_status[num][split_point:] + " " + jack_status.enc_status[num]
+- status_pad.addstr(map_track_num[num], 0, front)
+- status_pad.addstr(map_track_num[num], len(front), middle, A_REVERSE)
+- status_pad.addstr(map_track_num[num], len(front + middle), end)
++ try:
++ status_pad.addstr(map_track_num[num], 0, front)
++ status_pad.addstr(map_track_num[num], len(front), middle, A_REVERSE)
++ status_pad.addstr(map_track_num[num], len(front + middle), end)
++ except error:
++ pass
+ else:
+- status_pad.addstr(map_track_num[num], 0, (jack_ripstuff.printable_names[num] + ": " + jack_status.dae_status[num] + " " + jack_status.enc_status[num]))
++ try:
++ status_pad.addstr(map_track_num[num], 0, (jack_ripstuff.printable_names[num] + ": " + jack_status.dae_status[num] + " " + jack_status.enc_status[num]))
++ except error:
++ pass
+
+ dummy = """
+ if ripper == "cdparanoia" and track in dae_tracks or (track in enc_queue and track not in mp3s_done):
diff --git a/debian/patches/99a_correct-category-list.patch b/debian/patches/99a_correct-category-list.patch
new file mode 100644
index 0000000..c35c302
--- /dev/null
+++ b/debian/patches/99a_correct-category-list.patch
@@ -0,0 +1,54 @@
+Cédric Boutillier <cedric.boutillier@gmail.com> reports:
+
+When I try to send a submission to a freedb server, the list of
+categories appearing on the screen does not contain 'blues' (which is a
+freedb category) and contains 'null' (which is not a freedb category).
+
+I think that a few changes must be made to jack_freedb.py:
+* when the list is fetched from the server, it is unnecessarily
+ initialised with "null"
+* subtract 1 to the index to get the correct category
+* When the list is displayed, the index is running from 1 to len(cat)-1,
+ missing the first item.
+
+The attached patch solved the problem for me, to be applied after the
+already very long list of patches.
+
+See http://bugs.debian.org/536165
+
+--- jack-3.1.1+cvs20050801/jack_freedb.py 2009-07-07 21:04:06.000000000 +0200
++++ jack-3.1.1+cvs20050801-cb/jack_freedb.py 2009-07-07 21:03:22.000000000 +0200
+@@ -761,11 +761,11 @@
+ def choose_cat(cat = ["blues", "classical", "country", "data", "folk", "jazz", "misc", "newage", "reggae", "rock", "soundtrack"]):
+ print "choose a category:"
+ cat.sort()
+- for i in range(1, len(cat)):
+- print "%2d" % i + ".) " + cat[i]
++ for i in range(0, len(cat)):
++ print "%2d" % (i+1) + ".) " + cat[i]
+
+ x = -1
+- while x < 0 or x > len(cat) - 1:
++ while x < 0 or x > len(cat):
+ if jack_progress.status_all.has_key('freedb_cat') and jack_progress.status_all['freedb_cat'][-1] in cat:
+ input = raw_input(" 0.) none of the above (default='%s'): " % jack_progress.status_all['freedb_cat'][-1])
+ if not input:
+@@ -782,7 +782,7 @@
+ print "ok, aborting."
+ sys.exit(0)
+
+- return cat[x]
++ return cat[x-1]
+
+ def do_freedb_submit(file, cd_id, cat = None):
+ import httplib
+@@ -798,7 +798,7 @@
+ cat = choose_cat()
+
+ elif buf[0:3] == "210":
+- cat = ["null", ]
++ cat = []
+ while 1:
+ buf = f.readline()
+ if not buf:
+