def parse(ticket):
    ticket['state'] = 'parsing'
    ticket.save()
    if 'data_md5' not in ticket:
        ticket.fail('Attempt to parse ticket, but no data_md5 found')
        return
    p = PLUGINS.get(ticket['format'])
    if not p:
        ticket.fail(ticket['format'] % 'Parser plugin for format %s not found')
        return
    # Make sure the downloaded content is in the cache
    download_cache_directory = config['download_cache_directory']
    in_path = os.path.join(download_cache_directory, ticket['data_md5'])
    if not os.path.exists(in_path):
        ticket.fail('Downloaded content for %s not found' % in_path)
        return
    p = subprocess.Popen(p['_path'], shell=True, stdin=open(in_path), stdout=subprocess.PIPE, stderr=subprocess.PIPE)    
    data = p.stdout.read()
    md5sum = hashlib.md5(data).hexdigest()
    download_cache_directory = config['download_cache_directory']    
    out_path = os.path.join(download_cache_directory, md5sum)
    open(out_path, 'wb').write(data)
    
    ticket['data_json'] = md5sum
    if ticket.get('only_parse') == True:
        ticket['state'] = 'done'
    else:
        ticket['state'] = 'parsed'
    # Check if there is any data in the stderr of the parser
    # If so, add it to the ticket as potential feedback
    data_stderr = p.stderr.read()
    if len(data_stderr) > 0:
        ticket['parse_feedback'] = data_stderr
    ticket.save()
dataset/ETHPy150Open okfn/bibserver/bibserver/ingest.py/parse/swapped operands of `%`