diff options
Diffstat (limited to 'jack')
-rwxr-xr-x | jack | 291 |
1 files changed, 291 insertions, 0 deletions
@@ -0,0 +1,291 @@ +#!/usr/bin/env python +### jack - extract audio from a CD and encode it using 3rd party software +### Copyright (C) 1999-2004 Arne Zellentin <zarne@users.sf.net> + +### This program is free software; you can redistribute it and/or modify +### it under the terms of the GNU General Public License as published by +### the Free Software Foundation; either version 2 of the License, or +### (at your option) any later version. + +### This program is distributed in the hope that it will be useful, +### but WITHOUT ANY WARRANTY; without even the implied warranty of +### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +### GNU General Public License for more details. + +### You should have received a copy of the GNU General Public License +### along with this program; if not, write to the Free Software +### Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +### If you want to comment on this program, contact me: zarne@users.sf.net ### +### Visit the homepage: http://www.home.unix-ag.org/arne/jack/ + +### see CHANGELOG for recent changes in this program +### see TODO if you want to see what needs to be implemented + +import os +import sys +import time +import wave +import types +import posix +import string +import select +import signal +import pprint +import traceback + +from jack_globals import * + +import jack_version +import jack_misc +import jack_mp3 +import jack_argv +import jack_rc +import jack_helpers +import jack_targets +import jack_freedb +import jack_display +import jack_term +import jack_children +import jack_tag +import jack_workers +import jack_utils +import jack_ripstuff +import jack_encstuff +import jack_checkopts +import jack_status +import jack_functions +import jack_main_loop +import jack_progress +import jack_prepare + + +############################################################################## +###################### M A I N ############################################### +############################################################################## + +# say hello... +print "This is", jack_version.prog_name, jack_version.prog_version, jack_version.prog_copyright, jack_version.prog_devemail + +### interpret options +global_cf = jack_rc.load(cf, cf['global_rc']['val']) +jack_checkopts.checkopts(cf, global_cf) +cf.rupdate(global_cf, "global_rc") +user_cf = jack_rc.load(cf, cf['user_rc']['val']) +jack_checkopts.checkopts(cf, user_cf) +cf.rupdate(user_cf, "user_rc") +help, argv_cf = jack_argv.parse_argv(cf, sys.argv) +jack_checkopts.checkopts(cf, argv_cf) +cf.rupdate(argv_cf, "argv") +if help: + jack_argv.show_usage(cf, long=help-1) + sys.exit(0) +debug("global_cf: " + `global_cf`) +debug("user_cf: " + `user_cf`) +debug("argv_cf: " + `argv_cf`) + +jack_checkopts.consistency_check(cf) + +if cf['save_args']['val'] == 1: + count = jack_rc.save(cf['user_rc']['val'], cf) + info("%d options saved in %s" % (count, cf['user_rc']['val'])) + sys.exit() + +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 +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) +if cf['_check_toc']: + jack_prepare.check_toc() + sys.exit(0) + +### (3a) read and interpret toc_file +is_submittable, track1_offset = jack_prepare.read_toc_file() + +### (3b) 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) + +#XXX## (5) read progress info into status + +jack_ripstuff.all_tracks_orig = [] +for i in jack_ripstuff.all_tracks: + jack_ripstuff.all_tracks_orig.append(i[:]) + +status = jack_prepare.init_status() + +### (6) update progress file at user's request (operation mode) +if cf['_upd_progress']: + jack_prepare.update_progress(todo) + sys.exit(0) + +### (7) now read in the progress file +status = jack_prepare.read_progress(status, todo) + +### (8) 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 +freedb_rename = 0 +if cf['_query_if_needed']: + 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() + +### (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) + 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") + sys.exit(0) + +### (11) undo renaming (operation mode) +if cf['_undo_rename']: + jack_prepare.undo_rename(status, todo) + sys.exit(0) + +#### Reorder if told so +if cf['_reorder']: + todo.sort(jack_utils.cmp_toc) + todo.reverse() + +#### check how much bytes we can burn +if cf['space_from_argv']['history'][-1][0] == "argv": + space = jack_ripstuff.raw_space = cf['_space_from_argv'] +else: + space = jack_ripstuff.raw_space = jack_functions.df() + +#### check what is already there +space, remove_q, wavs_todo, mp3s_todo, dae_queue, enc_queue = jack_prepare.what_todo(space, todo) + +if cf['_todo_exit']: # print what needs to be done, then exit + jack_prepare.print_todo(todo, wavs_todo, mp3s_todo) + sys.exit(0) + +# now mp3s_todo contains the tracks where the wavs only need to be coded and +# wavs_todo lists those tracks which need to be dae'd end enc'd. The dae_queue +# has been filled from wavs_todo (todo is superflous now). The main_loop +# will handle the tracks in mp3s_todo. + +### make sure we have enough space to rip the whole thing +jack_prepare.check_space(space, wavs_todo, mp3s_todo) + +cf['_max_load'] = cf['_max_load'] + cf['_encoders'] #XXX + +if not cf['_dont_work'] and dae_queue: # check if inserted cd matches toc. + jack_prepare.check_cd() # why? paranoia or needed? XXX + if cf['_rip_from_device']: + all_tracks_on_cd = jack_functions.gettoc(cf['_toc_prog']) + if not cf['_force'] and not jack_utils.cmp_toc_cd(jack_ripstuff.all_tracks_orig, all_tracks_on_cd, what=(NUM, LEN)): + error("you did not insert the right cd") + +### if we have work to do, we may have to remove some files first +if remove_q: + jack_prepare.remove_files(remove_q) + +### bail out now if told so +if cf['_dont_work']: + info("quitting now as requested.") + sys.exit(0) + +### install signal handlers +signal.signal(signal.SIGTERM, jack_display.sig_handler) +signal.signal(signal.SIGINT, jack_display.sig_handler) +signal.signal(signal.SIGQUIT, jack_display.sig_handler) +signal.signal(signal.SIGHUP, jack_display.sig_handler) + + + #\ /# +#########> real work starts here <############################################# + #/ \# + +global_error = None +if (wavs_todo or mp3s_todo): + jack_ripstuff.gen_printable_names(jack_tag.track_names, todo) + jack_term.init(cf['_terminal'], cf['_xtermset_enable']) + jack_display.init() + try: + jack_term.enable() + global_error = jack_main_loop.main_loop(mp3s_todo, wavs_todo, space, dae_queue, enc_queue, track1_offset) + except SystemExit: + jack_term.disable() + print jack_display.options_string + print "--- Last status: ---------------------------------------------------------------" + jack_status.print_status(form = 'short') + sys.exit(0) + except: + jack_term.disable() + warning("abnormal exit") + traceback.print_exc() + sys.exit(1) +# Set the files we have processed but this may still be overwritten by +# jack_tag.tag() called below. +os.environ["JACK_JUST_ENCODED"] = "\n".join([x[NAME] + ext for x in mp3s_todo]) +os.environ["JACK_JUST_RIPPED"] = "\n".join([x[NAME] + ".wav" for x in wavs_todo]) + +jack_term.disable() +if cf['_query_when_ready']: + info("querying...") + if jack_freedb.freedb_query(jack_freedb.freedb_id(jack_ripstuff.all_tracks), jack_ripstuff.all_tracks, cf['_freedb_form_file']): + 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) + if err: + error("could not read freedb file") + +if jack_term.term_type == "curses": + if jack_display.options_string: + print jack_display.options_string + print "The final status was:" + jack_status.print_status(form = 'short') + +if global_error: + if cf['_exec_when_done']: + os.system(cf['_exec_err']) + error("aborting because of previous error(s) [%i]." % global_error) + +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()))) + +if cf['_remove_files']: + print "cleaning up in", os.getcwd() + for i in [cf['_progress_file'], cf['_toc_file'], cf['_def_toc'], cf['_freedb_form_file'], cf['_freedb_form_file'] + ".bak"]: + if os.path.exists(i): + os.remove(i) + +if cf['_exec_when_done']: + os.system(cf['_exec_no_err']) + +jack_display.exit() # call the cleanup function & exit + + +############################################################################### +################################## #################################### +################################## T H E #################################### +################################## E N D #################################### +################################## #################################### +############################################################################### |