Exemplo n.º 1
0
def what_todo(space, todo):
    #### check what is already there
    wavs_todo = []
    mp3s_todo = []
    remove_q  = []
    ext = jack_targets.targets[jack_helpers.helpers[cf['_encoder']]['target']]['file_extension']

    for track in todo:
        wavs_todo.append(track)
        mp3s_todo.append(track)

    jack_encstuff.mp3s_ready = []
    for track in todo:
        mp3 = track[NAME] + ext
        if os.path.exists(mp3):
            if cf['_overwrite']:
                space = space + jack_utils.filesize(mp3)
                remove_q.append(mp3)
                jack_status.enc_status[track[NUM]] = "will o/w file."
            elif not cf['_force'] and not jack_status.enc_status[track[NUM]]:
                space = space + jack_utils.filesize(mp3)
                remove_q.append(mp3)
                jack_status.enc_status[track[NUM]] = "no encoder run."
            # with vbr encoded files can't legally be too small
            # but to reduce confusion, the check is then removed:
            elif not cf['_vbr'] and jack_utils.filesize(mp3) <= jack_functions.tracksize(track)[ENC] * 0.99: # found by trial'n'err
                space = space + jack_utils.filesize(mp3)
                remove_q.append(mp3)
                jack_status.enc_status[track[NUM]] = "encoded file too small by " + jack_functions.pprint_i(jack_functions.tracksize(track)[ENC] - jack_utils.filesize(mp3)) + "."
            elif not cf['_vbr'] and jack_utils.filesize(mp3) >= jack_functions.tracksize(track)[ENC] * 1.05: # found by trial'n'err
                space = space + jack_utils.filesize(mp3)
                remove_q.append(mp3)
                jack_status.enc_status[track[NUM]] = "enc. file too large by " + jack_functions.pprint_i(jack_utils.filesize(mp3) - jack_functions.tracksize(track)[ENC]) + "."
            else:
                mp3s_todo.remove(track)
                jack_encstuff.mp3s_ready.append(track)
        else:
            if jack_status.enc_status[track[NUM]]:
                jack_status.enc_status[track[NUM]] = "[file lost-doing again]"

    jack_ripstuff.wavs_ready = []
    for track in todo:
        wav = track[NAME] + ".wav"
        if os.path.exists(wav):
            if cf['_overwrite']:
                space = space + jack_utils.filesize(wav)
                remove_q.append(wav)
                jack_status.dae_status[track[NUM]] = "Existing WAV will be overwritten."
            elif jack_utils.filesize(wav) == jack_functions.tracksize(track)[WAV] and jack_status.dae_status[track[NUM]]:
                wavs_todo.remove(track)
                jack_ripstuff.wavs_ready.append(track)
            elif jack_utils.filesize(wav) == jack_functions.tracksize(track)[WAV]:
                space = space + jack_utils.filesize(wav)
                remove_q.append(wav)
                jack_status.dae_status[track[NUM]] =     " ---- [Existing WAV not done by jack.]"
                if jack_status.enc_status[track[NUM]] == "[file lost-doing again]":
                    jack_status.enc_status[track[NUM]] = ""
            else:
                space = space + jack_utils.filesize(wav)
                remove_q.append(wav)
                jack_status.dae_status[track[NUM]] =     " ---- [Existing WAV was not complete.]"
                if jack_status.enc_status[track[NUM]] == "[file lost-doing again]":
                    jack_status.enc_status[track[NUM]] = ""
        else:
            if jack_status.dae_status[track[NUM]]:
                if jack_status.enc_status[track[NUM]] == "[file lost-doing again]":
                    jack_status.dae_status[track[NUM]] = " ---- [    both lost, doing again    ]"
                    jack_status.enc_status[track[NUM]] = ""
                elif cf['_keep_wavs'] or track not in jack_encstuff.mp3s_ready:
                    jack_status.dae_status[track[NUM]] = " ---- [ WAV lost, doing again        ]"

    if cf['_only_dae']:
        cf['_keep_wavs'] = 1

    if not cf['_keep_wavs']:
        for track in todo:
            if track in jack_encstuff.mp3s_ready and track in wavs_todo:
                wavs_todo.remove(track)

    if cf['_reorder']:
        mp3s_todo.sort(jack_utils.cmp_toc)

    dae_queue = []                  # This stores the tracks to rip
    enc_queue = []                  # WAVs go here to get some codin'

    for track in wavs_todo:
        dae_queue.append(track)     # copy track to dae + code in queue
        if track in mp3s_todo:
            mp3s_todo.remove(track) # remove mp3s which are not there yet

    if cf['_only_dae']:             # if only_dae nothing is encoded _at_all_.
        mp3s_todo = []

    # overwrite cached bitrates with those from argv
    if cf['bitrate']['history'][-1][0] == "argv":
        for i in wavs_todo:
            i[RATE] = cf['_bitrate']
        for i in mp3s_todo:
            i[RATE] = cf['_bitrate']

    return space, remove_q, wavs_todo, mp3s_todo, dae_queue, enc_queue
Exemplo n.º 2
0
def do_freedb_submit(file, cd_id, cat = None):
    import httplib

    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 = []
            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())

    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 + "]: ")
    if x:
        email = x

    info("Submitting...")
    selector = '/~cddb/submit.cgi'
    proxy = ""
    if os.environ.has_key('http_proxy'):
        proxy = os.environ['http_proxy']
        def splittype(url):
            import re
            _typeprog = re.compile('^([^/:]+):')
            match = _typeprog.match(url)
            if match:
                    scheme = match.group(1)
                    return scheme, url[len(scheme) + 1:]
            return None, url

        def splithost(url):
            import re
            _hostprog = re.compile('^//([^/]+)(.*)$')
            match = _hostprog.match(url) 
            if match: return match.group(1, 2)
            return None, url

        type, proxy = splittype(proxy)
        host, selector2 = splithost(proxy)
        h = httplib.HTTP(host)
        h.putrequest('POST', 'http://' + freedb_servers[cf['_freedb_server']]['host'] + selector)
    else:
        h = httplib.HTTP(freedb_servers[cf['_freedb_server']]['host'])
        h.putrequest('POST', '/~cddb/submit.cgi')
    h.putheader('Category', cat)
    h.putheader('Discid', cd_id)
    h.putheader('User-Email', email)
    if cf['_debug']:
        debug("will submit in test-mode, changes are not applied and you'll get an email which contains the data you submitted.")
        h.putheader('Submit-Mode', 'test')
    else:
        h.putheader('Submit-Mode', 'submit')
    h.putheader('Charset', 'UTF-8')
    if cf['_debug']:
        h.putheader('X-Cddbd-Note', 'Submission will not be applied to database if --debug is on.')
    else:
        h.putheader('X-Cddbd-Note', 'data submitted with ' + prog_name + ' (http://jack.sf.net)')
    h.putheader('Content-Length', str(jack_utils.filesize(file)))
    h.endheaders()
    # The user just wrote the file with a text editor so we assume that it
    # is in their locale.
    f = codecs.open(file, "r", locale.getpreferredencoding())
    try:
        text = f.read()
    except UnicodeDecodeError:
        print "The freedb file does not match your current locale. Please convert it"
        print "to " + locale.getpreferredencoding() + " manually."
        sys.exit(1)
    h.send(text.encode("utf-8"))
    f.close()

    print

    err, msg, headers = h.getreply()
    f = h.getfile()
    if proxy:
        if err != 200:
            error("proxy: " + `err` + " " + msg + f.read())
        else:
            buf = f.readline()
            err, msg = buf[0:3], buf[4:]
            
    # lets see if it worked:
    if err == 404:
        print "This server doesn't seem to support database submission via http."
        print "consider submitting via mail (" + progname + " -m). full error:\n"
    print err, msg
Exemplo n.º 3
0
def main_loop(mp3s_todo, wavs_todo, space, dae_queue, enc_queue,
              track1_offset):
    global_error = 0  # remember if something went wrong
    actual_load = -2  # this is always smaller than max_load
    waiting_load = 0  # are we waiting for the load to drop?
    waiting_space = 0  # are we waiting for disk space to be freed?
    space_waiting = 0  # how much space _running_ subprocesses will consume
    space_adjust = 0  # by how much space has been modified
    blocked = 0  # we _try_ do detect deadlocks
    cycles = 0  # it's sort of a timer
    last_update = 0  # screen updates are done once per second
    pause = 0  # no new encoders are started if pause==1
    flags = "[   ]"  # runtime controllable flags
    enc_running = 0  # what is going on?
    dae_running = 0  # what is going on?

    rotate = "/-\\|"
    rotate_ball = " .o0O0o."
    rot_cycle = len(rotate)
    rot_ball_cycle = len(rotate_ball)
    rot_count = 0
    global_done = 0
    first_encoder = 1
    ext = jack_targets.targets[jack_helpers.helpers[cf['_encoder']]
                               ['target']]['file_extension']
    global_blocks = jack_functions.tracksize(
        wavs_todo)[BLOCKS] + jack_functions.tracksize(mp3s_todo)[BLOCKS]

    #####################
    ### MAIN LOOP ###
    #####################

    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])
            space = space - jack_functions.tracksize(mp3s_todo[0])[ENC]
            jack_status.enc_stat_upd(mp3s_todo[0][NUM], "waiting for encoder.")
            mp3s_todo = mp3s_todo[1:]

            # start new DAE subprocess

        elif (len(enc_queue) + enc_running) < (
                cf['_read_ahead'] + cf['_encoders']
        ) and dae_queue and dae_running < cf['_rippers'] and (
            (jack_functions.tracksize(dae_queue[0])[BOTH] < space) or
            (cf['_only_dae']
             and jack_functions.tracksize(dae_queue[0])[WAV] < space) or
            (cf['_otf']
             and jack_functions.tracksize(dae_queue[0])[ENC] < space)):
            waiting_space = 0
            this_is_ok = 1
            if pause:
                this_is_ok = 0
                jack_status.dae_stat_upd(dae_queue[0][NUM],
                                         "Paused. Press 'c' to continue.")
            elif cf['_rip_from_device']:
                all_tracks_on_cd = jack_functions.gettoc(cf['_toc_prog'])
                if not jack_utils.cmp_toc_cd(jack_ripstuff.all_tracks_orig,
                                             all_tracks_on_cd,
                                             what=(NUM, LEN)):
                    while dae_queue:
                        track = dae_queue[0]
                        dae_queue = dae_queue[1:]
                        jack_status.dae_stat_upd(
                            track[NUM], "Wrong disc - aborting this track")
                    global_error = global_error + 1
                    this_is_ok = 0
            if this_is_ok:
                if cf['_only_dae']:
                    space_waiting = space_waiting + jack_functions.tracksize(
                        dae_queue[0])[WAV]
                    space = space - jack_functions.tracksize(dae_queue[0])[WAV]
                elif cf['_otf']:
                    space_waiting = space_waiting + jack_functions.tracksize(
                        dae_queue[0])[ENC]
                    space = space - jack_functions.tracksize(dae_queue[0])[ENC]
                else:
                    space_waiting = space_waiting + jack_functions.tracksize(
                        dae_queue[0])[BOTH]
                    space = space - jack_functions.tracksize(
                        dae_queue[0])[BOTH]
                dae_running = dae_running + 1
                track = dae_queue[0]
                dae_queue = dae_queue[1:]
                if cf['_otf']:
                    # note: image_reader can't do otf at the moment.
                    jack_status.dae_stat_upd(
                        track[NUM], ":DAE: waiting for status report...")
                    if cf['_encoder'] in ("lame", "gogo", "flac", "mppenc"):
                        jack_status.enc_stat_upd(
                            track[NUM],
                            "[no otf status for %s]" % cf['_encoder'])
                    else:
                        jack_status.enc_stat_upd(track[NUM],
                                                 "waiting for encoder.")
                    enc_running = enc_running + 1
                    if first_encoder:
                        first_encoder = 0
                        global_start = time.time()
                    data = jack_workers.start_new_otf(track, cf['_ripper'],
                                                      cf['_encoder'])
                    jack_children.children.append(data['rip'])
                    jack_children.children.append(data['enc'])
                else:
                    if jack_status.enc_status[track[NUM]]:
                        jack_status.enc_cache[
                            track[NUM]] = jack_status.enc_status[track[NUM]]
                        jack_status.enc_stat_upd(track[NUM], "[...]")
                    jack_status.dae_stat_upd(
                        track[NUM], ":DAE: waiting for status report...")
                    if cf['_rip_from_device']:
                        jack_children.children.append(
                            jack_workers.start_new_ripper(
                                track, cf['_ripper']))
                    elif cf['_image_file']:
                        jack_children.children.append(
                            jack_workers.ripread(track, track1_offset))
                    else:
                        jack_status.dae_stat_upd(
                            track[NUM], ":?AE: don't know how to rip this!")

                        # start new encoder subprocess

        if enc_queue and enc_running < cf['_encoders']:
            if jack_functions.tracksize(
                    enc_queue[0])[ENC] <= space + space_waiting:
                waiting_space = 0
                actual_load = jack_misc.loadavg()
                if actual_load < cf['_max_load']:
                    waiting_load = 0
                    enc_running = enc_running + 1
                    track = enc_queue[0]
                    enc_queue = enc_queue[1:]
                    jack_status.enc_stat_upd(track[NUM],
                                             "waiting for encoder...")
                    jack_children.children.append(
                        jack_workers.start_new_encoder(track, cf['_encoder']))
                    if first_encoder:
                        first_encoder = 0
                        global_start = time.time()
                else:
                    waiting_load = 1

                    # check for subprocess output

        readfd = [sys.stdin.fileno()]
        for i in jack_children.children:
            readfd.append(i['fd'])
        try:
            rfd, wfd, xfd = select.select(readfd, [], [],
                                          cf['_update_interval'])
        except:
            rfd, wfd, xfd = [], [], []
            jack_term.tmod.sig_winch_handler(None, None)

            # check for keyboard commands

        if sys.stdin.fileno() in rfd:
            last_update = last_update - cf['_update_interval']
            cmd = jack_term.tmod.getkey()
            sys.stdin.flush()
            if string.upper(cmd) == "Q":
                jack_display.exit()
            elif not pause and string.upper(cmd) == "P":
                pause = 1
                flags = flags[:1] + "P" + flags[2:]
            elif string.upper(
                    cmd) == "C" or pause and string.upper(cmd) == "P":
                pause = 0
                flags = flags[:1] + " " + flags[2:]
            elif not flags[3] == "e" and string.upper(cmd) == "E":
                for i in jack_children.children:
                    if i['type'] == "encoder":
                        os.kill(i['pid'], signal.SIGSTOP)
                        flags = flags[:3] + "e" + flags[4:]
            elif flags[3] == "e" and string.upper(cmd) == "E":
                for i in jack_children.children:
                    if i['type'] == "encoder":
                        os.kill(i['pid'], signal.SIGCONT)
                        flags = flags[:3] + " " + flags[4:]
            elif not flags[2] == "r" and string.upper(cmd) == "R":
                for i in jack_children.children:
                    if i['type'] == "ripper":
                        os.kill(i['pid'], signal.SIGSTOP)
                        flags = flags[:2] + "r" + flags[3:]
            elif flags[2] == "r" and string.upper(cmd) == "R":
                for i in jack_children.children:
                    if i['type'] == "ripper":
                        os.kill(i['pid'], signal.SIGCONT)
                        flags = flags[:2] + " " + flags[3:]
            elif string.upper(cmd) == "U":
                cycles = 29  # do periodic stuff _now_
            else:
                jack_term.tmod.move_pad(cmd)
                if cmd == 'KEY_RESIZE':
                    continue
                last_update = time.time()

        # read from file with activity
        for i in jack_children.children:
            if i['fd'] in rfd:
                if os.uname()[0] == "Linux" and i['type'] != "image_reader":
                    try:
                        x = i['file'].read()
                    except (IOError, ValueError):
                        pass
                else:
                    read_chars = 0
                    x = ""
                    while read_chars < jack_helpers.helpers[
                            i['prog']]['status_blocksize']:
                        try:
                            xchar = i['file'].read(1)
                        except (IOError, ValueError):
                            break
                        x = x + xchar
                        read_chars = read_chars + 1
                        try:
                            rfd2, wfd2, xfd2 = select.select([i['fd']], [], [],
                                                             0.0)
                        except:
                            rfd2, wfd2, xfd2 = [], [], []
                            jack_term.tmod.sig_winch_handler(None, None)
                        if i['fd'] not in rfd2:
                            break
                # put read data into child's buffer
                i['buf'] = i['buf'] + x

                if jack_helpers.helpers[i['prog']].has_key('filters'):
                    for fil in jack_helpers.helpers[i['prog']]['filters']:
                        i['buf'] = fil[0].sub(fil[1], i['buf'])

                i['buf'] = i['buf'][-jack_helpers.
                                    helpers[i['prog']]['status_blocksize']:]

        # check for exiting child processes
        if jack_children.children:
            respid, res = os.waitpid(-1, os.WNOHANG)
            if respid != 0:
                last_update = last_update - cf[
                    '_update_interval']  # ensure info is printed
                new_ch = []
                exited_proc = []
                for i in jack_children.children:
                    if i['pid'] == respid:
                        if exited_proc != []:
                            error("pid " + ` respid ` +
                                  " found at multiple child processes")
                        exited_proc = i
                    else:
                        new_ch.append(i)
                if not exited_proc:
                    error("unknown process (" + ` respid ` + ") has exited")
                jack_children.children = new_ch
                x = ""
                try:
                    x = exited_proc['file'].read()
                except (IOError, ValueError):
                    pass
                exited_proc['buf'] = (
                    exited_proc['buf'] +
                    x)[-jack_helpers.
                       helpers[exited_proc['prog']]['status_blocksize']:]
                exited_proc['file'].close()

                global_error = global_error + res
                track = exited_proc['track']
                num = track[NUM]
                stop_time = time.time()
                speed = (track[LEN] / float(CDDA_BLOCKS_PER_SECOND)) / (
                    stop_time - exited_proc['start_time'])

                if exited_proc['type'] in ("ripper", "image_reader"):
                    dae_running = dae_running - 1
                    if cf['_exec_when_done'] and exited_proc[
                            'type'] == "ripper" and dae_running == 0 and len(
                                dae_queue) == 0:
                        os.system(cf['_exec_rip_done'])
                    if not res:
                        if not exited_proc['otf']:
                            if os.path.exists(track[NAME] + ".wav"):
                                if jack_functions.tracksize(
                                        track)[WAV] != jack_utils.filesize(
                                            track[NAME] + ".wav"):
                                    res = 242
                                    jack_status.dae_stat_upd(
                                        num,
                                        jack_status.get_2_line(
                                            exited_proc['buf']))
                            else:
                                jack_status.dae_stat_upd(
                                    num,
                                    jack_status.get_2_line(exited_proc['buf']))
                                res = 243
                            global_error = global_error + res
                    if res and not cf['_sloppy']:
                        if os.path.exists(track[NAME] + ".wav"):
                            os.remove(track[NAME] + ".wav")
                            space = space + jack_functions.tracksize(
                                track)[WAV]
                            if cf['_otf']:
                                os.kill(exited_proc['otf-pid'], signal.SIGTERM)
                                if os.path.exists(track[NAME] + ext):
                                    os.remove(track[NAME] + ext)
                                space = space + jack_functions.tracksize(
                                    track)[ENC]
                            if not cf['_otf'] and not cf[
                                    '_only_dae'] and track not in jack_encstuff.mp3s_ready:
                                space = space + jack_functions.tracksize(
                                    track)[ENC]
                            jack_status.dae_stat_upd(
                                num, 'DAE failed with status ' + ` res ` +
                                ", wav removed.")
                    else:
                        if exited_proc['type'] == "image_reader":
                            jack_status.dae_stat_upd(
                                num,
                                jack_status.get_2_line(exited_proc['buf']))
                        else:
                            if exited_proc['otf'] and jack_helpers.helpers[
                                    exited_proc['prog']].has_key(
                                        'otf-final_status_fkt'):
                                exec(jack_helpers.helpers[exited_proc['prog']]
                                     ['otf-final_status_fkt']) in globals(
                                     ), locals()
                            else:
                                last_status = None  # (only used in cdparanoia)
                                exec(jack_helpers.helpers[exited_proc['prog']]
                                     ['final_status_fkt']) in globals(
                                     ), locals()
                            jack_status.dae_stat_upd(num, final_status)
                        if jack_status.enc_cache[num]:
                            jack_status.enc_stat_upd(
                                num, jack_status.enc_cache[num])
                            jack_status.enc_cache[num] = ""
                        jack_functions.progress(num, "dae",
                                                jack_status.dae_status[num])
                        if not cf['_otf'] and not cf[
                                '_only_dae'] and track not in jack_encstuff.mp3s_ready:
                            if waiting_space:
                                mp3s_todo.append(track)
                                space = space + jack_functions.tracksize(
                                    track)[ENC]
                            else:
                                jack_status.enc_stat_upd(
                                    num, 'waiting for encoder.')
                                enc_queue.append(track)
                    space_waiting = space_waiting - jack_functions.tracksize(
                        track)[WAV]

                elif exited_proc['type'] == "encoder":
                    enc_running = enc_running - 1
                    # completed vbr files shouldn't be to small, but this still
                    # caused confusion so again, vbr is an exception:
                    if not cf['_vbr'] and not res and jack_functions.tracksize(
                            track)[ENC] * 0.99 > jack_utils.filesize(
                                track[NAME] + ext):
                        res = 242
                        global_error = global_error + res
                    if res:
                        global_blocks = global_blocks - exited_proc['track'][
                            LEN]
                        global_start = global_start + exited_proc[
                            'elapsed'] / (enc_running + 1)
                        if global_start > time.time():
                            global_start = time.time()
                        if os.path.exists(track[NAME] + ext):
                            # mp3enc doesn't report errors when out of disk space...
                            os.remove(track[NAME] + ext)
                        space = space + jack_functions.tracksize(track)[ENC]
                        jack_status.enc_stat_upd(
                            num, 'coding failed, err#' + ` res `)
                    else:
                        global_done = global_done + exited_proc['track'][LEN]
                        if cf['_vbr']:
                            rate = int(
                                (jack_utils.filesize(track[NAME] + ext) *
                                 0.008) / (track[LEN] / 75.0))
                        else:
                            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]

                else:
                    error("child process of unknown type (" +
                          exited_proc['type'] + ") exited")
                if global_error:
                    jack_display.smile = " :-["

        space_adjust += orig_space - space

        if last_update + cf['_update_interval'] <= time.time():
            last_update = time.time()

            # interpret subprocess output

            for i in jack_children.children:
                if i['type'] == "ripper":
                    if len(i['buf']) == jack_helpers.helpers[
                            i['prog']]['status_blocksize']:
                        if i['otf'] and jack_helpers.helpers[
                                i['prog']].has_key('otf-status_fkt'):
                            exec(jack_helpers.helpers[i['prog']]
                                 ['otf-status_fkt']) in globals(), locals()
                        else:
                            exec(jack_helpers.helpers[i['prog']]
                                 ['status_fkt']) in globals(), locals()
                        if 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']:
                        tmp_d = {'i': i.copy(), 'percent': 0}
                        try:
                            exec(jack_helpers.helpers[i['prog']]
                                 ['percent_fkt']) in globals(), tmp_d
                        except:
                            tmp_d['percent'] = 0
                            debug("error in percent_fkt of %s." % ` i `)
                        i['percent'] = tmp_d['percent']
                        if i['percent'] > 0:
                            i['elapsed'] = time.time() - i['start_time']
                            speed = ((i['track'][LEN] /
                                      float(CDDA_BLOCKS_PER_SECOND)) *
                                     (i['percent'] / 100)) / i['elapsed']
                            eta = (100 -
                                   i['percent']) * i['elapsed'] / i['percent']
                            eta_ms = "%02i:%02i" % (eta / 60, eta % 60)
                            jack_status.enc_stat_upd(
                                i['track'][NUM], '%2i%% done, ETA:%6s, %sx' %
                                (i['percent'], eta_ms,
                                 jack_functions.pprint_speed(speed)))
                            #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'], 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'] + "\".")

            cycles = cycles + 1
            if cycles % 30 == 0:
                if cf['_recheck_space'] and not cf['space_from_argv'][
                        'history'][-1][0] == "argv":
                    actual_space = jack_functions.df()
                    if space_adjust:
                        diff = actual_space - space
                        if diff > space_adjust:
                            space = space + space_adjust
                            space_adjust = 0
                            waiting_space = 0
                        else:
                            space = space + diff
                            space_adjust = space_adjust - diff
                    else:
                        if actual_space < space:
                            space_adjust = space - actual_space
                            space = actual_space

            if space_adjust and enc_running == 0 and dae_running == 0:
                waiting_space = waiting_space + 1
            if not waiting_space >= 2 and not waiting_load and enc_running == 0 and dae_running == 0:
                blocked = blocked + 1
            else:
                blocked = 0

            total_done = global_done
            for i in jack_children.children:
                total_done = total_done + (i['percent'] /
                                           100) * i['track'][LEN]
            elapsed = time.time() - global_start
            if global_blocks > 0:
                percent = total_done / global_blocks
            else:
                percent = 0
            if percent > 0 and elapsed > 40:
                eta = ((1 - percent) * elapsed / percent)
                eta_hms = " ETA=%i:%02i:%02i" % (eta / 3600,
                                                 (eta % 3600) / 60, eta % 60)
            else:
                eta_hms = ""

            if string.strip(flags[1:-1]):
                print_flags = " " + flags
            else:
                print_flags = ""
            if dae_running:
                rot = rotate_ball[rot_count % rot_ball_cycle]
            else:
                rot = rotate[rot_count % rot_cycle]
            rot_count = rot_count + 1

            # print status

            if blocked > 2:
                jack_display.special_line = " ...I feel blocked - quit with 'q' if you get bored... "
                if blocked > 5:
                    space = jack_functions.df() - cf['_keep_free']
            elif waiting_load and waiting_space >= 2:
                jack_display.special_line = " ...waiting for load (%.2f)" % actual_load + ") < %.2f" % cf[
                    '_max_load'] + " and for " + jack_functions.pprint_i(
                        space_adjust, "%i %sBytes") + " to be freed... "
            elif waiting_space >= 2:
                jack_display.special_line = " ...waiting for " + jack_functions.pprint_i(
                    space_adjust, "%i %sBytes") + " to be freed.... "
            elif waiting_load:
                jack_display.special_line = " ...waiting for load (%.2f) to drop below %.2f..." % (
                    actual_load, cf['_max_load'])
            else:
                jack_display.special_line = None

            jack_display.bottom_line =  "(" + rot + ") " \
                + "SPACE:" * (space_adjust != 0) \
                + "space:" * (space_adjust == 0) \
                + jack_functions.pprint_i(space, "%i%sB") \
                + (" waiting_WAVs:%02i" % len(enc_queue)) \
                + " DAE:" + `cf['_rippers'] - dae_running` + "+" + `dae_running` \
                + " ENC:" + `cf['_encoders'] - enc_running` + "+" + `enc_running` \
                + eta_hms \
                + " errors: " + `global_error` \
                + jack_display.smile + print_flags

            jack_term.tmod.update(jack_display.special_line,
                                  jack_display.bottom_line)

    return global_error
Exemplo n.º 4
0
def tag(freedb_rename):
    global a_artist, a_title

    ext = jack_targets.targets[jack_helpers.helpers[cf['_encoder']]['target']]['file_extension']

    if cf['_vbr'] and not cf['_only_dae']:
        total_length = 0
        total_size = 0
        for i in jack_ripstuff.all_tracks_todo_sorted:
            total_length = total_length + i[LEN]
            total_size = total_size + jack_utils.filesize(i[NAME] + ext)

    if cf['_set_id3tag'] and not jack_targets.targets[jack_helpers.helpers[cf['_encoder']]['target']]['can_posttag']:
        cf['_set_id3tag'] = 0

    # maybe export?
    if jack_freedb.names_available:
        a_artist = track_names[0][0] # unicode
        a_title = track_names[0][1] # unicode
        p_artist = locale_names[0][0] # string
        p_title = locale_names[0][1] # string

    if cf['_set_id3tag'] or freedb_rename:
        jack_m3u.init()
        # 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:
            sys.stdout.write(".") ; sys.stdout.flush()
            mp3name = i[NAME] + ext
            wavname = i[NAME] + ".wav"
            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']:
                if len(t_name) > 30:
                    if string.find(t_name, "(") != -1 and string.find(t_name, ")") != -1:
                        # we only use the last comment
                        t_comm = string.split(t_name, "(")[-1]
                        if t_comm[-1] == ")":
                            t_comm = t_comm[:-1]
                            if t_comm[-1] == " ":
                                t_comm = t_comm[:-1]
                            t_name2 = string.replace(t_name, " (" + t_comm + ") ", "")
                            t_name2 = string.replace(t_name2, " (" + t_comm + ")", "")
                            t_name2 = string.replace(t_name2, "(" + t_comm + ") ", "")
                            t_name2 = string.replace(t_name2, "(" + t_comm + ")", "")
                        else:
                            t_comm = ""
                if jack_helpers.helpers[cf['_encoder']]['target'] == "mp3":
                    if cf['_write_id3v2']:
                        _set_id3_tag(
                            mp3name, eyed3.id3.ID3_V2_4,  'utf-8', a_title,
                            t_name, (i[NUM],len(jack_ripstuff.all_tracks_orig)),
                            t_artist, cf['_id3_genre'], cf['_id3_year'], None,
                            int(i[LEN] * 1000.0 / 75 + 0.5)
                        )
                    if cf['_write_id3v1']:
                        # encoding ??
                        _set_id3_tag(
                            mp3name, eyed3.id3.ID3_V1_1,  'latin1',
                            a_title, t_name,
                            (i[NUM],len(jack_ripstuff.all_tracks_orig)),
                            t_artist, cf['_id3_genre'], cf['_id3_year'], t_comm,
                            int(i[LEN] * 1000.0 / 75 + 0.5)
                        )
                elif jack_helpers.helpers[cf['_encoder']]['target'] == "flac":
                    if flac:
                        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 python-mutagen package."
                        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)
                    oggi = vf.comment()
                    oggi.clear()
                    oggi.add_tag('ALBUM', a_title.encode("utf-8"))
                    oggi.add_tag('TRACKNUMBER', `i[NUM]`)
                    oggi.add_tag('TITLE', t_name.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:
                        oggi.add_tag('DATE', `cf['_id3_year']`)
                    oggi.write_to(mp3name)
            if freedb_rename:
                newname = jack_freedb.filenames[i[NUM]]
                try:
                    i[NAME] = unicode(i[NAME], "utf-8")
                except UnicodeDecodeError:
                    i[NAME] = unicode(i[NAME], "latin-1")
                if i[NAME] != newname:
                    p_newname = newname.encode(locale.getpreferredencoding(), "replace")
                    u_newname = newname
                    newname = newname.encode(cf['_charset'], "replace")
                    p_mp3name = i[NAME].encode(locale.getpreferredencoding(), "replace") + ext
                    p_wavname = i[NAME].encode(locale.getpreferredencoding(), "replace") + ".wav"
                    ok = 1
                    if os.path.exists(newname + ext):
                        ok = 0
                        print 'NOT renaming "' + p_mp3name + '" to "' + p_newname + ext + '" because dest. exists.'
                        if cf['_keep_wavs']:
                            print 'NOT renaming "' + p_wavname + '" to "' + p_newname + ".wav" + '" because dest. exists.'
                    elif cf['_keep_wavs'] and os.path.exists(newname + ".wav"):
                        ok = 0
                        print 'NOT renaming "' + p_wavname + '" to "' + p_newname + ".wav" + '" because dest. exists.'
                        print 'NOT renaming "' + p_mp3name + '" to "' + p_newname + ext + '" because WAV dest. exists.'
                    if ok:
                        if not cf['_only_dae']:
                            try:
                                os.rename(mp3name, newname + ext)
                            except OSError:
                                error('Cannot rename "%s" to "%s" (Filename is too long or has unusable characters)' % (p_mp3name, p_newname + ext))
                            jack_m3u.add(newname + ext)
                        if cf['_keep_wavs']:
                            os.rename(wavname, newname + ".wav")
                            jack_m3u.add_wav(newname + ".wav")
                        jack_functions.progress(i[NUM], "ren", "%s-->%s" % (i[NAME], u_newname))
                    elif cf['_silent_mode']:
                        jack_functions.progress(i[NUM], "err", "while renaming track")
        print

    if not cf['_silent_mode']:
        if jack_freedb.names_available:
            print "Done with \"" + p_artist + " - " + p_title + "\"."
        else:
            print "All done.",
        if cf['_set_id3tag'] and cf['_id3_year'] != -1:
            print "Year: %4i" % cf['_id3_year'],
            if cf['_id3_genre'] == -1: print
        if cf['_set_id3tag'] and cf['_id3_genre'] != -1:
            if cf['_id3_genre'] <0 or cf['_id3_genre'] > len(id3genres):
                print "Genre: [unknown]"
            else:
                print "Genre: %s" % id3genres[cf['_id3_genre']]
        if cf['_vbr'] and not cf['_only_dae']:
            print "Avg. bitrate: %03.0fkbit" % ((total_size * 0.008) / (total_length / 75))
        else:
            print

    if jack_m3u.m3u:
        os.environ["JACK_JUST_ENCODED"] = "\n".join(jack_m3u.m3u)
    if jack_m3u.wavm3u:
        os.environ["JACK_JUST_RIPPED"] = "\n".join(jack_m3u.wavm3u)
    jack_m3u.write()
Exemplo n.º 5
0
def guesstoc(names):
    "Return track list based on guessed lengths"
    num = 1
    start = 0
    erg = []
    progr = []
    for i in names:
        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)
            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)
            ])
        elif i_ext == ".WAV":
            x = sndhdr.whathdr(i)
            if not x:
                error("this is not WAV-format: " + i)
            if x != ('wav', 44100, 2, -1, 16):
                error("unsupportet format " + ` x ` + " in " + i)
            blocks = jack_utils.filesize(i)
            blocks = blocks - 44  # substract WAV header
            extra_bytes = blocks % CDDA_BLOCKSIZE
            if not extra_bytes == 0:
                warning("this is not CDDA block-aligned: " + ` i `)
                yes = raw_input(
                    "May I strip %d bytes (= %.4fseconds) off the end? " %
                    (extra_bytes, extra_bytes / 2352.0 / 75.0))
                if not string.upper((yes + "x")[0]) == "Y":
                    print "Sorry, I can't process non-aligned files (yet). Bye!"
                    sys.exit()
                f = open(i, "r+")
                f.seek(-extra_bytes, 2)
                f.truncate()
                f.close()
                blocks = blocks - extra_bytes
            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   ]"])
        elif i_ext == ".OGG":
            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":
            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("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
        start = start + blocks
    for i in progr:  # this is deferred so that it is only written if no
        # files fail
        progress(i)
    return erg
Exemplo n.º 6
0
def ripread(track, offset=0):
    "rip one track from an image file."
    data = {}
    start_time = time.time()
    pid, master_fd = pty.fork()  # this could also be done with a pipe, anyone?
    if pid == CHILD:
        #debug:
        #so=open("/tmp/stdout", "w")
        #sys.stdout = so
        #se=open("/tmp/stderr", "w+")
        #sys.stderr = se
        default_signals()

        # FIXME: all this offset stuff has to go, track 0 support has to come.

        print ":fAE: waiting for status report..."
        sys.stdout.flush()
        hdr = sndhdr.whathdr(cf['_image_file'])
        my_swap_byteorder = cf['_swap_byteorder']
        my_offset = offset
        if hdr:

            ## I guess most people use cdparanoia 1- (instead of 0- if applicable)
            ## for image creation, so for a wav file use:

            image_offset = -offset

        else:
            if string.upper(cf['_image_file'])[-4:] == ".CDR":
                hdr = ('cdr', 44100, 2, -1, 16)  # Unknown header, assuming cdr
                #
                ## assume old cdrdao which started at track 1, not at block 0
                image_offset = -offset

            elif string.upper(cf['_image_file'])[-4:] == ".BIN":
                hdr = ('bin', 44100, 2, -1, 16)  # Unknown header, assuming bin
                #
                ## assume new cdrdao which starts at block 0, byteorder is reversed.
                my_swap_byteorder = not my_swap_byteorder
                image_offset = 0

            elif string.upper(cf['_image_file'])[-4:] == ".RAW":
                hdr = ('bin', 44100, 2, -1, 16)  # Unknown header, assuming raw
                image_offset = 0

            else:
                debug("unsupported image file " + cf['_image_file'])
                posix._exit(4)

        expected_filesize = jack_functions.tracksize(
            jack_ripstuff.all_tracks)[CDR] + CDDA_BLOCKSIZE * offset
        #
        ## WAVE header is 44 Bytes for normal PCM files...
        #
        if hdr[0] == 'wav':
            expected_filesize = expected_filesize + 44

        if abs(jack_utils.filesize(cf['_image_file']) -
               expected_filesize) > CDDA_BLOCKSIZE:
            # we *do* allow a difference of one frame
            debug("image file size mismatch, aborted. %d != %d" %
                  (jack_utils.filesize(cf['_image_file']), expected_filesize))
            posix._exit(1)

        elif hdr[0] == 'wav' and (hdr[1], hdr[2], hdr[4]) != (44100, 2, 16):
            debug("unsupported WAV, need CDDA_fmt, aborted.")
            posix._exit(2)

        elif hdr[0] not in ('wav', 'cdr', 'bin'):
            debug("unsupported: " + hdr[0] + ", aborted.")
            posix._exit(3)

        else:
            f = open(cf['_image_file'], 'r')
            #
            ## set up output wav file:
            #
            wav = wave.open(track[NAME] + ".wav", 'w')
            wav.setnchannels(2)
            wav.setsampwidth(2)
            wav.setframerate(44100)
            wav.setnframes(0)
            wav.setcomptype('NONE', 'not compressed')
            #
            ## calculate (and seek to) position in image file
            #
            track_start = (track[START] + image_offset) * CDDA_BLOCKSIZE
            if hdr[0] == 'wav':
                track_start = track_start + 44
            f.seek(track_start)
            #
            ## copy / convert the stuff
            #
            for i in range(0, track[LEN]):
                buf = array.array("h")
                buf.fromfile(f, 1176)  # CDDA_BLOCKSIZE / 2
                if not my_swap_byteorder:  # this is inverted as WAVE swabs them anyway.
                    buf.byteswap()
                wav.writeframesraw(buf.tostring())
                if i % 1000 == 0:
                    print ":fAE: Block " + ` i ` + "/" + ` track[LEN] ` + (
                        " (%2i%%)" % (i * 100 / track[LEN]))
                    sys.stdout.flush()
            wav.close()
            f.close()

            stop_time = time.time()
            read_speed = track[LEN] / CDDA_BLOCKS_PER_SECOND / (stop_time -
                                                                start_time)
            if read_speed < 100:
                print "[%2.0fx]" % read_speed,
            else:
                print "[99x]",
            if hdr[0] in ('bin', 'wav'):
                print "[      - read from image -     ]"
            else:
                print "[cdr-WARNING, check byteorder !]"
            sys.stdout.flush()
            posix._exit(0)
    else:  # we are not the child
        data['start_time'] = start_time
        data['pid'] = pid
        data['fd'] = master_fd
        data['file'] = os.fdopen(master_fd)
        data['cmd'] = ""
        data['buf'] = ""
        data['type'] = "image_reader"
        data['prog'] = "builtin"
        data['track'] = track
        data['percent'] = 0
        data['otf'] = 0
        data['elapsed'] = 0
    return data