def field_values_from_separated_file(fh, delimiter, quote_character, fields=None):
  if fields is None:
    field_names = None
  else:
    field_names = [field['name'].strip() for field in fields]

  if fields is None:
    timestamp_fields = None
  else:
    timestamp_fields = [field['name'].strip() for field in fields if field['type'] in DATE_FIELD_TYPES]

  if fields is None:
    integer_fields = None
  else:
    integer_fields = [field['name'].strip() for field in fields if field['type'] in INTEGER_FIELD_TYPES]

  if fields is None:
    decimal_fields = None
  else:
    decimal_fields = [field['name'].strip() for field in fields if field['type'] in DECIMAL_FIELD_TYPES]

  if fields is None:
    boolean_fields = None
  else:
    boolean_fields = [field['name'].strip() for field in fields if field['type'] in BOOLEAN_FIELD_TYPES]

  content = fh.read()
  headers = None

  while content:
    last_newline = content.rfind('\n')
    if last_newline > -1:
      next_chunk = fh.read()
      # If new line is quoted, skip this iteration and try again.
      if content[last_newline - 1] == '"' and next_chunk:
        content += next_chunk
        continue
      else:
        if headers is None:
          csvfile = StringIO.StringIO(content[:last_newline])
        else:
          csvfile = StringIO.StringIO('\n' + content[:last_newline])
        content = content[last_newline + 1:] + next_chunk
    else:
      if headers is None:
        csvfile = StringIO.StringIO(content)
      else:
        csvfile = StringIO.StringIO('\n' + content)
      content = fh.read()

    # First line is headers
    if headers is None:
      headers = next(csv.reader(csvfile, delimiter=smart_str(delimiter), quotechar=smart_str(quote_character)))
      headers = [name.strip() for name in headers]

    # User dict reader
    reader = csv.DictReader(csvfile, fieldnames=headers, delimiter=smart_str(delimiter), quotechar=smart_str(quote_character))

    remove_keys = None
    for row in reader:
      row = dict([(force_unicode(k), force_unicode(v, errors='ignore')) for k, v in row.iteritems()]) # Get rid of invalid binary chars and convert to unicode from DictReader

      # Remove keys that aren't in collection
      if remove_keys is None:
        if field_names is None:
          remove_keys = []
        else:
          remove_keys = set(row.keys()) - set(field_names)
      if remove_keys:
        for key in remove_keys:
          del row[key]

      # Parse dates
      if timestamp_fields:
        tzinfo = pytz.timezone(settings.TIME_ZONE)
        for key in timestamp_fields:
          if key in row:
            dt = parse(row[key])
            if not dt.tzinfo:
              dt = tzinfo.localize(dt)
            row[key] = dt.astimezone(pytz.utc).strftime('%Y-%m-%dT%H:%M:%SZ')

      # Parse decimal
      if decimal_fields:
        for key in decimal_fields:
          if key in row:
            row[key] = float(row[key])

      # Parse integer
      if integer_fields:
        for key in integer_fields:
          if key in row:
            row[key] = int(row[key])

      # Parse boolean
      if boolean_fields:
        for key in boolean_fields:
          if key in row:
            row[key] = str(row[key]).lower() == "true"

      # Add mock id random value
      if 'id' not in row:
        row['id'] = str(uuid.uuid4())

      yield row
dataset/ETHPy150Open cloudera/hue/desktop/libs/indexer/src/indexer/utils.py/field_values_from_separated_file/original